package com.xjrsoft.common.utils;


import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xjrsoft.common.enums.WeChatType;
import com.xjrsoft.module.organization.dto.WeChatDepartDto;
import com.xjrsoft.module.organization.dto.WeChatUserDto;
import com.xjrsoft.module.system.vo.WeChatUserInfo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

@Component
@Data
@Slf4j
public class WeChatUtil {
    @Value("${xjrsoft.enterpriseWeChat.corpid}")
    public String appKey;

    @Value("${xjrsoft.enterpriseWeChat.secret}")
    public String appSecret;

    @Value("${xjrsoft.enterpriseWeChat.secret1}")
    public String appSecret1;

    @Value("${xjrsoft.enterpriseWeChat.agentid}")
    public Integer agentid;

    @Value("${xjrsoft.mpWeChat.appKey}")
    public String mpAppKey;

    @Value("${xjrsoft.mpWeChat.appSecret}")
    public String mpAppSecret;

    @Value("${xjrsoft.appletWeChat.appKey}")
    public String appletAppKey;

    @Value("${xjrsoft.appletWeChat.appSecret}")
    public String appletAppSecret;

    @Value("${xjrsoft.weChatMessageTemplate.commonTemplate}")
    public String commonTemplate;

    @Value("${xjrsoft.weChatMessageTemplate.assessmentTemplate}")
    public String assessmentTemplate;

    //公众号获取Openid
    public WeChatUserInfo getMpOpenid(String code) {
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("appid", mpAppKey);
        paramMap.put("secret", mpAppSecret);
        paramMap.put("code", code);
        paramMap.put("grant_type", "authorization_code");
        String result = HttpUtil.get("https://api.weixin.qq.com/sns/oauth2/access_token", paramMap);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.containsKey("errcode")) {
            //throw new MyException(result);
            return null;
        }
        return jsonObject.toJavaObject(WeChatUserInfo.class);
    }

    // 小程序
    public  WeChatUserInfo getOpenid(String code) {
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("appid", appletAppKey);
        paramMap.put("secret", appletAppSecret);
        paramMap.put("js_code", code);
        paramMap.put("grant_type", "authorization_code");
        String result = HttpUtil.get("https://api.weixin.qq.com/sns/jscode2session", paramMap);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.containsKey("errcode")) {
            //throw new MyException(result);
            return null;
        }
        return jsonObject.toJavaObject(WeChatUserInfo.class);
    }

    //获取通讯录或发消息token
    public String getToken(WeChatType type) {
        HashMap<String, Object> paramMap = new HashMap<>();
        String url = "https://api.weixin.qq.com/cgi-bin/token";
        String key = "";
        if (WeChatType.WEMINI == type) {
            url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
            paramMap.put("corpsecret", appSecret);
            paramMap.put("corpid", appKey);
            key = String.format("access_token_%s",appKey);
        } else if (WeChatType.WEWEB == type) {
            paramMap.put("grant_type", "client_credential");
            paramMap.put("appid", mpAppKey);
            paramMap.put("secret", mpAppSecret);
            key = String.format("access_token_%s",mpAppKey);
        }
        // 判断redis中token是否过期
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);
        String accessToken = redisUtil.get(key);
        if (StrUtil.isNotBlank(accessToken) && !accessToken.equals("null")) {
            return accessToken;
        }

        String result = HttpUtil.get(url, paramMap);
        JSONObject jsonObject = JSONObject.parseObject(result);
        String token = jsonObject.get("access_token").toString();
        // 缓存1小时
        redisUtil.set(key,token,3600);

        return token;
    }

    //根据所有部门信息
    public List<WeChatDepartDto> getDepartmentList(Long dept_id) {
        String token = this.getToken(WeChatType.WEMINI);
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("access_token", token);
        if (dept_id != null) {
            paramMap.put("id", dept_id);
        }
        String result = HttpUtil.get("https://qyapi.weixin.qq.com/cgi-bin/department/list", paramMap);
        JSONObject jsonObject = JSONObject.parseObject(result);
        Object department = jsonObject.get("department");
        List<WeChatDepartDto> weChatDepartDtos = JSONObject.parseArray(department.toString(), WeChatDepartDto.class);
        return weChatDepartDtos;
    }

    //获取部门的所有用户信息
    public List<WeChatUserDto> getDepartmentUser(Long dept_id) {
        String token = this.getToken(WeChatType.WEMINI);
            HashMap<String, Object> paramMap = new HashMap<>();
            paramMap.put("access_token", token);
            paramMap.put("department_id", dept_id);
            paramMap.put("fetch_child", 1);
            String result = HttpUtil.get("https://qyapi.weixin.qq.com/cgi-bin/user/list", paramMap);
          JSONObject jsonObject = JSONObject.parseObject(result);
            Object department = jsonObject.get("userlist");
        List<WeChatUserDto> weChatUserDtos = JSONObject.parseArray(department.toString(), WeChatUserDto.class);
        return weChatUserDtos;
    }

    //公众号发送文本消息给用户
    public Boolean sendMessage(String content, String userId) {

        String token = this.getToken(WeChatType.WEWEB);
        JSONObject object = new JSONObject();
        JSONArray touser=new JSONArray();
        touser.add(userId);
        object.put("touser", touser);
        object.put("msgtype", "text");
        JSONObject text = new JSONObject();
        text.put("content", content);
        object.put("text",text);
        String result = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token="+token, JSONObject.toJSONString(object));
        System.out.printf(result);
        return true;
    }

    //{
    //           "touser":"OPENID",
    //           "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
    //           "url":"http://weixin.qq.com/download",
    //           "miniprogram":{
    //             "appid":"xiaochengxuappid12345",
    //             "pagepath":"index?foo=bar"
    //           },
    //           "client_msg_id":"MSG_000001",
    //           "data":{
    //                   "keyword1":{
    //                       "value":"巧克力"
    //                   },
    //                   "keyword2": {
    //                       "value":"39.8元"
    //                   },
    //                   "keyword3": {
    //                       "value":"2014年9月22日"
    //                   }
    //           }
    //       }
    public Boolean sendTemplateMessage(JSONObject object){
        String active = SpringUtil.getActiveProfile();
        if("dev".equals(active)){
            log.info("测试环境，无法执行数据推送");
            return false;
        }
        String token = this.getToken(WeChatType.WEWEB);
        String result = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+token, JSONObject.toJSONString(object));
        System.out.printf(result);
        return true;
    }

    public String getTicket(String type) {
        String token = this.getToken(WeChatType.WEWEB);
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("access_token", token);
        paramMap.put("type", type);
        String result = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/ticket/getticket", paramMap);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.containsKey("ticket")) {
            //throw new MyException(result);
            return jsonObject.get("ticket").toString();
        } else {
            return "";
        }
    }

    public HashMap<String, Object> SdkSign(String url,String type) throws Exception {
        String nonceStr = UUID.randomUUID().toString();
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);
        String signature = "";
        String jsapiTicket = getTicket(type);

        String string1 = "jsapi_ticket=" + jsapiTicket +
                "&noncestr=" + nonceStr +
                "&timestamp=" + timestamp +
                "&url=" + url;
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());

            HashMap<String, Object> resultMap = new HashMap<>();
            resultMap.put("url",url);
//            resultMap.put("jsapi_ticket",jsapiTicket);
            resultMap.put("nonceStr",nonceStr);
            resultMap.put("timestamp",timestamp);
            resultMap.put("signature",signature);

            return  resultMap;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }
}
