package org.springblade.app.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springblade.app.dto.AccessTokenDto;
import org.springblade.app.dto.DataDto;
import org.springblade.app.util.JsonUtils;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;

import org.apache.commons.lang.StringUtils;
import org.springblade.common.constant.CommonConstant;
import org.springblade.common.utils.Base64DecodeMultipartFileUtils;
import org.springblade.common.utils.Base64DecodedMultipartFile;
import org.springblade.common.utils.MultipartFileUtils;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.tool.api.R;
import org.springblade.estate.entity.ApplyUser;
import org.springblade.estate.feign.IApplyUserClient;
import org.springblade.estate.vo.ApplyUserVO;
import org.springblade.person.entity.HouseUser;
import org.springblade.person.entity.Member;
import org.springblade.person.feign.IHouseUserClient;
import org.springblade.person.feign.IMemberClient;
import org.springblade.person.vo.HouseUserVO;
import org.springblade.person.vo.MemberVO;
import org.springblade.resource.feign.IOssEndpointClient;
import org.springblade.system.expand.entity.WxConf;
import org.springblade.system.expand.feign.IWxConfClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * Created By lidexi in 2021/4/23
 **/
@RestController
@RequiredArgsConstructor
@Api(value = "", tags = "接口")
@RequestMapping(value = "/app/miniprogram")
@Slf4j
public class MiniProgramController {


	private final IWxConfClient wxConfClient;
	private final RestTemplate restTemplate;
	private final IMemberClient memberClient;
	private final IApplyUserClient applyUserClient;
	private final IHouseUserClient houseUserClient;
	private final RedisTemplate<String,String> redisTemplate;
	private final IOssEndpointClient ossEndpointClient;


	/**
	 * 短信缓存名称
	 */
	private final static String VERIFICATION_CODE = "verification:code";

	/**
	 * 自动生成二维码请求路径
	 */
	private String GENERATE_CODE_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit";

	/**
	 * 功能描述: 获取微信小程序用户的openid
	 * @param map {
	 *            js_code : 微信小程序端获取的js_code，时效5分钟,
	 *
	 *            }
	 * @return ResultBean<hashMap> 返回结果
	 *
	 *
	 */
	@PostMapping(value = "/getOpenid")
	public Map<String,Object> getOpenid(@RequestBody Map<String,String> map){
		Map<String,Object> hashMap = new HashMap<>();
		//result_code:0-失败  1-成功
		hashMap.put("result_code", 0);
		hashMap.put("result_msg", "openid获取失败");
		try{
			String js_code = map.get("js_code");
			String app_type = map.get("app_type");
			if(StringUtils.isBlank(js_code)){
				hashMap.put("result_msg", "js_code不能为空");
				return hashMap;
			}
			WxConf wxConf = new WxConf();
			wxConf.setAppType(Integer.valueOf(app_type));

			WxConf conf = this.wxConfClient.detail(wxConf);
			if(conf == null){
				hashMap.put("result_msg", "机构未配置微信参数，请联系管理员");
				return hashMap;
			}
			//获取openid的微信接口
			String wxURI = "https://api.weixin.qq.com/sns/jscode2session?appid="+conf.getMiniAppId()+"&secret="+conf.getMiniAppSecret()+"&grant_type=authorization_code";
			wxURI = wxURI+"&js_code="+js_code;
			ResponseEntity<String> responseEntity = restTemplate.getForEntity(wxURI, String.class);
			//返回正常
			if(responseEntity.getStatusCodeValue()==200){
				String body = responseEntity.getBody();
				Map<String,String> result = JsonUtils.jsonToPojo(body, Map.class);
				String openid = result.get("openid");
				String session_key = result.get("session_key");
				if(StringUtils.isNotBlank(openid)&&StringUtils.isNotBlank(session_key)){
					hashMap.put("result_code", 1);
					hashMap.put("result_msg", "openid和sessionKey获取成功");
					hashMap.put("openid", result.get("openid"));
					hashMap.put("session_key",result.get("session_key"));
					hashMap.put("appletType", conf.getAppletType());
				}else{
					log.info("从微信接口获取openid失败:"+body);
				}
			}else{
				hashMap.put("result_msg", "从微信接口获取openid失败");
				log.info("从微信接口获取openid失败:"+responseEntity.getStatusCodeValue()+":"+responseEntity.getStatusCode());
			}
		}catch (Exception e){
			log.error("异常", e);
			hashMap.put("result_msg", "后台程序异常");
		}
		return hashMap;
	}


	/**
	 * 功能描述: 通过openid获取会员信息
	 * @param map {
	 *            openid    :   微信小程序账号下的微信账号唯一标识,
	 *            org_id    :   机构授权org_id，机构id
	 *            token     :   对接令牌
	 *            }
	 * @return ResultBean<hashMap> 返回结果
	 *
	 *
	 */
	@PostMapping(value = "/getMemberByOpenid")
	public Map<String,Object> getMemberByOpenid(@RequestBody Map<String,String> map){
		Map<String,Object> hashMap = new HashMap<>();
		hashMap.put("result_code", 0);
		hashMap.put("result_msg", "没有获取到相关会员信息");
		try{

			String openid = map.get("openid");


			if(StringUtils.isBlank(openid)){
				hashMap.put("result_msg", "openid不能为空");
				return hashMap;
			}
			Member member = new Member();
			member.setOpenid(openid);
			MemberVO memberVO = this.memberClient.detail(member);
			if(memberVO == null){
				hashMap.put("result_msg", "会员不存在");
				return hashMap;
			}

			HouseUser houseUser = new HouseUser();
			houseUser.setMemberId(memberVO.getId());
			boolean anyHousePass = false;
			List<HouseUserVO> list = houseUserClient.list(houseUser);
			if (CollUtil.isNotEmpty(list)) {
				anyHousePass = true;
			}
			if(member!=null){
				hashMap.put("result_code", 1);
				hashMap.put("result_msg", "获取会员信息成功");
				hashMap.put("member", memberVO);
				hashMap.put("anyHousePass",anyHousePass);

			}
		}catch (Exception e){
			log.error("异常", e);
			hashMap.put("result_msg", "后台程序异常");
		}
		return hashMap;
	}



	@PostMapping(value = "/ws/geocoder/v1/location")
	public Map<String,Object> wxLocation(@RequestBody Map<String,String> map){

		RestTemplate restTemplate = new RestTemplate();
		String location = map.get("location");
		String[] latitude_longitude = location.split(",");
		String latitude = latitude_longitude[0];
		String longitude = latitude_longitude[1];
		String confKey = map.get("key");
		//获取腾讯地图接口
		String wxMapApi = "https://apis.map.qq.com/ws/geocoder/v1/?location=" + latitude + "," + longitude + "&key=" + confKey;
		ResponseEntity<String> responseEntity = restTemplate.getForEntity(wxMapApi, String.class);
		//返回正常
		Map<String,Object> hashMap = new HashMap<>();
		hashMap.put("result_code", 0);
		if(responseEntity.getStatusCodeValue()==200) {
			String body = responseEntity.getBody();
			Map<String, String> result = JsonUtils.jsonToPojo(body, Map.class);
			hashMap.put("result_code", 1);
			hashMap.put("result_msg", "获取行政区域成功");
			hashMap.put("result", result);
		}else{
			hashMap.put("result_msg", "获取行政区域失败");
		}
		return hashMap;
	}

	@PostMapping(value = "/ws/district/v1/getchildren")
	public Map<String,Object> getchildren(@RequestBody Map<String,String> map){
		RestTemplate restTemplate = new RestTemplate();
		String id = map.get("id");

		String key = map.get("key");
		//获取腾讯地图接口
		String wxMapApi = "https://apis.map.qq.com/ws/district/v1/getchildren?&id="+id+"&key=" + key;
		ResponseEntity<String> responseEntity = restTemplate.getForEntity(wxMapApi, String.class);
		//返回正常
		Map<String,Object> hashMap = new HashMap<>();
		hashMap.put("result_code", 0);
		if(responseEntity.getStatusCodeValue()==200) {
			String body = responseEntity.getBody();
			Map<String, String> result = JsonUtils.jsonToPojo(body, Map.class);
			hashMap.put("result_code", 1);
			hashMap.put("result_msg", "获取成功");
			hashMap.put("result", result);
		}else{
			hashMap.put("result_msg", "获取失败");
		}
		return hashMap;
	}

	@PostMapping("/getOpenData")
	public String getOpenData (@RequestBody DataDto dataDto){
		byte[] key = Base64.getDecoder().decode(dataDto.getSessionKey().replaceAll(" ","+"));
		byte[] iv = Base64.getDecoder().decode(dataDto.getIv().replaceAll(" ","+"));
		byte[] content = Base64.getDecoder().decode(dataDto.getEncryptedData().replaceAll(" ","+"));
		AES aes = new AES(Mode.CBC, Padding.PKCS5Padding,key,iv);
		return new String(aes.decrypt(content));
	}


	@PostMapping("/generateCode")
	public String generateCode(@RequestBody Map<String,String> params) throws IOException {

		String url = GENERATE_CODE_URL+"?access_token="+params.get("access_token");
		params.remove("access_token");

		HttpResponse response = HttpRequest.post(url)
			.body(JSON.toJSONString(params),"application/json")
			.execute();
		byte[] bytes = response.bodyBytes();
		String base64 = Base64.getEncoder().encodeToString(bytes);
		MultipartFile file  = Base64DecodeMultipartFileUtils.base64ToMultipart(Base64DecodeMultipartFileUtils.imageFormatToPng("data:image/png;base64," + base64));
//		MultipartFile file = MultipartFileUtils.base64ToMultipart(base64);
		//图片上传

		R<BladeFile> uploadFile = ossEndpointClient.putFile(file);

		if(uploadFile != null &&uploadFile.getData() != null){
			return uploadFile.getData().getLink();
		}
		return "";
	}



	@PostMapping("/getAccessToken")
	public String getAccessToken (@RequestBody AccessTokenDto accessTokenDto){
		HttpResponse response = HttpRequest.get("https://api.weixin.qq.com/cgi-bin/token"+"?appid="+accessTokenDto.getAppId()+"&secret="+accessTokenDto.getSecret()+"&grant_type="+accessTokenDto.getGrantType()).execute();
		return response.body();
	}


}
