package org.springblade.wx.service;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.protocol.HTTP;
import org.springblade.common.cache.WechatCache;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.wx.config.ConfigForClient;
import org.springblade.wx.config.ConfigForMall;
import org.springblade.wx.config.ConfigForShop;
import org.springblade.wx.config.WeChatConfig;
import org.springblade.wx.constant.MessageTemplate;
import org.springblade.wx.constant.MiniProgramType;
import org.springblade.wx.constant.WeChatApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author: lianghanqiang
 * @description: 微信服务
 * @since: 9/6/21 -- 8:09 PM
 */
@Service
@Slf4j
public class WeChatService {

	@Autowired
	BladeRedis bladeRedis;

	/**
	 * 小程序发送模板消息
	 *
	 * @return*/
	public HttpResponse sendTemplateMessage(String openId, MessageTemplate messageTemplate,JSONObject content, String page, MiniProgramType miniProgramType){

		Assert.notNull(messageTemplate,()->{ throw new ServiceException("找不到响应的消息模板"); });
		String token = fetchAccessToken(miniProgramType);
		String query = "?access_token="+token;
		HttpResponse execute = HttpRequest.post(WeChatApi.sendTemplateMessage.getApi() + query)
			.body(messageTemplate.buildRequestBody(openId, content, page))
			.execute();
		log.info("微信发送消息模板响应:{}",execute.body());
		return  execute;
	}

	/**
	 * 	获取小程序的AccessToken
	 * */
	public String fetchAccessToken(MiniProgramType type){

		WeChatConfig config = getConfig(type);
		String accessToken = WechatCache.getAccessToken(config.getAppId());

		//缓存没有请求微信
		if(Objects.isNull(accessToken)){
			HttpResponse response = HttpRequest.get(WeChatApi.fetchAccessToken.getApi())
				.form("grant_type", "client_credential")
				.form("appid", config.getAppId())
				.form("secret", config.getAppSecret())
				.execute();
			JSONObject jsonObject = JSON.parseObject(response.body());
			accessToken = jsonObject.getString("access_token");

			if (StringUtil.isNotBlank(accessToken)) {
				WechatCache.putAccessToken(config.getAppId(),accessToken);
			}
		}

		return accessToken;
	}

	/**
	 * 获取openId
	 * @return
	 */
	public JSONObject getOpenId(String code,MiniProgramType type){
		WeChatConfig config = getConfig(type);
		String appId = config.getAppId();
		String appSecret = config.getAppSecret();

		StringBuilder sb = new StringBuilder("https://api.weixin.qq.com/sns/jscode2session?appid=");
		sb.append(appId)
			.append("&secret=")
			.append(appSecret)
			.append("&js_code=")
			.append(code)
			.append("&grant_type=authorization_code");
		String url = sb.toString();
		String s = HttpUtil.get(url);
		JSONObject jsonObject = JSON.parseObject(s);
		return jsonObject;
	}

	/**
	 * OCR-营业执照
	 * @return
	 */
	public HttpResponse  ocrBizilicense(String imgUrl,MiniProgramType type){
		String token = fetchAccessToken(type);
		HttpResponse response = HttpRequest.post(WeChatApi.OCR_BIZLICENSE.buildUrl(imgUrl, token)).execute();
		return response;
	}

	/**
	 * OCR-身份证
	 * @return
	 */
	public HttpResponse  ocrIdcard(String imgUrl,MiniProgramType type){
		String token = fetchAccessToken(type);
		HttpResponse response = HttpRequest.post(WeChatApi.OCR_ID_CARD.buildUrl(imgUrl, token)).execute();
		return response;
	}

	/**
	 * OCR-银行卡
	 * @return
	 */
	public HttpResponse  ocrBank(String imgUrl,MiniProgramType type){
		String token = fetchAccessToken(type);
		HttpResponse response = HttpRequest.post(WeChatApi.OCR_BANK.buildUrl(imgUrl, token)).execute();
		return response;
	}

	/**
	 * 生成小程序码--无数量限制
	 * @return
	 */
	public HttpResponse getUnlimitCode(String queryData,MiniProgramType type,String page){
		String token = fetchAccessToken(type);
		Map<String,String> params = new HashMap(){{
			put("page",page);
			put("scene",queryData);
		}};
		HttpResponse response = HttpRequest.post(WeChatApi.getUnLimit.buildUrl(token)).header(HTTP.CONTENT_TYPE, "application/json").body(JSON.toJSONString(params)).execute();

		return response;
	}


	/**
	 * 获取对应小程序的配置文件
	 * */
	private WeChatConfig getConfig(MiniProgramType type){
		switch (type){
			case MALL:
				return SpringUtil.getBean(ConfigForMall.class);
			case SHOP:
				return SpringUtil.getBean(ConfigForShop.class);
			case CLIENT:
				return SpringUtil.getBean(ConfigForClient.class);
			default:
				return null;
		}
	}
}
