package com.jeequan.jeepay.thirdparty.service.wxmp;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.cache.RedisUtil;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchWxmpUser;
import com.jeequan.jeepay.core.interfaces.wxmp.IWxMpTemplateMsgService;
import com.jeequan.jeepay.core.model.DBWxMpConfig;
import com.jeequan.jeepay.core.model.wx.wxmp.WxUserInfo;
import com.jeequan.jeepay.model.CacheInfo;
import com.jeequan.jeepay.service.mapper.CacheTkMapper;
import com.jeequan.jeepay.thirdparty.model.WxmpServerContext;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.service.WxOAuth2Service;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpOAuth2ServiceImpl;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 微信公众号授权回调 code -> openid  实现类
 *
 * @author terrfly
 *
 * @date 2021/6/8 17:22
 */
@Service
@Slf4j
@AllArgsConstructor
public class WxMpTemplateMsgService implements IWxMpTemplateMsgService {

    @Autowired
    private WxmpServerContext wxmpServerContext;
    @Autowired
    private CacheTkMapper cacheTkMapper;

    @Override
    public WxUserInfo code2WxUserInfo(String code, DBWxMpConfig wxMpConfig) {

        try {
            WxMpService wxMpService = wxmpServerContext.getWxService(wxMpConfig);

            WxOAuth2Service wxOAuth2Service = new WxMpOAuth2ServiceImpl(wxMpService);
            WxOAuth2AccessToken accessToken = wxOAuth2Service.getAccessToken(code);

            WxOAuth2UserInfo wxOAuth2UserInfo = wxOAuth2Service.getUserInfo(accessToken, "zh_CN");

            WxUserInfo wxUserInfo = new WxUserInfo();
            BeanUtil.copyProperties(wxOAuth2UserInfo, wxUserInfo);

            return wxUserInfo;
        } catch (WxErrorException e) {
            log.error("获取微信授权信息失败", e);
        }

        return null;
    }

    @Override
    public void sendTemplateMessage(List<MchWxmpUser> userList, String templateMessage, DBWxMpConfig wxMpConfig,String templateId) {

        // 构造模板消息
        WxMpTemplateMessage wxMpTemplateMessage = new WxMpTemplateMessage();
        wxMpTemplateMessage.setTemplateId(templateId); //模板ID

        List<WxMpTemplateData> dataList = JSON.parseArray(templateMessage, WxMpTemplateData.class);
        wxMpTemplateMessage.setData(dataList); // 模板内容

        WxMpService wxService = wxmpServerContext.getWxService(wxMpConfig);

        Set<String> openIdSet = userList.stream().map(MchWxmpUser::getWxOpenId).collect(Collectors.toSet());

        for (String openId : openIdSet) {

            try {
                wxMpTemplateMessage.setToUser(openId);

                wxService.getTemplateMsgService().sendTemplateMsg(wxMpTemplateMessage);

                log.info("微信公众号消息获取access_token={}", RedisUtil.getString(CS.CACHE_KEY_WX_JAVA+":access_token:"+wxMpConfig.getWxAppId()));

                log.info("微信公众号消息发送成功，toOpenId={}, templateMessage={}", openId, templateMessage);
            }catch (Exception e) {
                log.error("微信公众号消息发送失败：{}", e.getMessage(), e);
            }
        }
    }


    /**
     * 发送消息扩展方法
     * @param userList
     * @param templateMessage
     * @param wxMpConfig
     */
//    @Override
//    public void sendTemplateMessageExtend(List<MchWxmpUser> userList, String templateMessage, DBWxMpConfig wxMpConfig) {
//        String accessToken = getExtAccessToken(wxMpConfig);
//        if(StringUtils.isEmpty(accessToken)){
//            sendTemplateMessage(userList,templateMessage,wxMpConfig,null);
//        }else{
//            String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
//            // 构造模板消息
//            String templateId = wxMpConfig.getPaySuccMsgTemplateId();
//            List<JSONObject> dataList = JSON.parseArray(templateMessage, JSONObject.class);
//            Set<String> openIdSet = userList.stream().map(MchWxmpUser::getWxOpenId).collect(Collectors.toSet());
//            JSONObject params = new JSONObject();
//            JSONObject data = new JSONObject();
//            for (JSONObject item:dataList) {
//                data.put(item.getString("name"),item);
//            }
//            params.put("template_id",templateId);
//            params.put("data",data);
//            for (String openId : openIdSet) {
//                try {
//                    params.put("touser",openId);
//                    log.info("微信模板请求参数：{}",JSON.toJSONString(params));
//                    HttpResponse response = HttpRequest.post(url).body(params.toString()).execute();
//                    if(!response.isOk()){
//                        log.info("消息发送失败");
//                        continue;
//                    }
//                    log.info("微信模板消息接口返回参数：{}",response.body());
//                    JSONObject respBody = JSON.parseObject(response.body());
//                    if(respBody.getInteger("errcode") != null && respBody.getInteger("errcode") != 0){
//                        log.info("微信模板消息发送失败：{}",respBody.getString("errmsg"));
//                        continue;
//                    }
//                }catch (Exception e) {
//                    log.error("微信公众号消息发送失败：{}", e.getMessage(), e);
//                }
//            }
//        }
//    }

    /**
     * 扩展方法获取accessToken
     * @param wxMpConfig
     * @return
     */
    private String getExtAccessToken(DBWxMpConfig wxMpConfig) {
        String keyCode = "accesstoken:" + wxMpConfig.getWxAppId();
        try {
            CacheInfo cacheInfo = cacheTkMapper.getKeyCode(keyCode);
            if(cacheInfo == null){
                return null;
            }
            return cacheInfo.getAccessToken();
        }catch (Exception e){
            return null;
        }
    }
}

