package com.storlead.wx.util;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.storlead.wx.pojo.vo.CorpWeChatDeptVO;
import com.storlead.wx.pojo.vo.CorpWeChatUserVO;
import com.storlead.wx.pojo.vo.SummaryInfoVO;
import com.storlead.wx.pojo.vo.WechatToken;
import com.storlead.wx.properties.CorpWeChatConstants;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.validation.constraints.NotNull;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;


/**
 * QyWechatUntil
 *
 * @author blank
 * @date 2021-3-8 上午 11:46
 */
@Slf4j
public class CorpWechatUtil {

    /**
     * 获取AccessToken
     *
     * @param url        "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET"
     * @param corpId     企业微信ID
     * @param corpSecret 企业微信应用的secret
     * @return cn.hutool.json.JSONObject
     * @author blank
     * @date 2021-3-8 上午 11:53
     */
    public static WechatToken getAccessToken(String url, @NotNull String corpId, @NotNull String corpSecret) {

        String resultStr = HttpUtil.get(url.replace("ID", corpId).replace("SECRET", corpSecret));
        if (StringUtils.isNotEmpty(resultStr)) {
            log.debug("accessToken---> {}", resultStr);
            JSONObject jsonResult = new JSONObject(resultStr);
            int errCode = jsonResult.getInt("errcode");
            String errMsg = jsonResult.getStr("errmsg");
            if (CorpWeChatConstants.RETURN_SUCCESS_CODE == errCode) {
                log.info("TOKEN 获取成功: {} ", jsonResult.getStr("access_token"));
                log.info("TOKEN 过期时间: {} 秒", jsonResult.getStr("expires_in"));

                return new WechatToken(CorpWeChatConstants.TOKEN_TYPE_ACCESS_TOKEN, jsonResult.getStr("access_token"));
            }
        }
        throw new RuntimeException("获取accessToken失败! " + resultStr);
    }

    /**
     * 获取 JS API TICKET
     *
     * @param url         "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKEN
     * @param accessToken accessToken
     * @return com.storlead.web.model.entity.WechatToken
     * @author blank
     * @date 2021-3-8 下午 3:23
     */
    public static WechatToken getJSApiTicket(@NotNull String url, @NotNull String accessToken) {

        String resultStr = HttpUtil.get(url.replace("ACCESS_TOKEN", accessToken));
        if (StringUtils.isNotEmpty(resultStr)) {
            log.debug("js ticket---> {}", resultStr);
            JSONObject jsonResult = new JSONObject(resultStr);
            int errCode = jsonResult.getInt("errcode");
            String errMsg = jsonResult.getStr("errmsg");
            if (CorpWeChatConstants.RETURN_SUCCESS_CODE == errCode) {
                log.info("ticket 获取成功: {} ", jsonResult.getStr("ticket"));
                log.info("TOKEN 过期时间: {} 秒", jsonResult.getStr("expires_in"));

                return new WechatToken(CorpWeChatConstants.TOKEN_TYPE_TICKET, jsonResult.getStr("ticket"));
            }
        }
        throw new ApiException("获取ticket失败! " + resultStr);
    }

    /**
     * 获取部门 如果不需要获取指定部门下的用户 而是获取全部用户 可以 直接调用 获取部门成员详情接口并将参数 DEPARTMENT_ID=1
     *
     * @param url         https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=ACCESS_TOKEN&id=ID
     * @param accessToken accessToken
     * @param deptId      不传的话查询所有部门
     * @return java.util.List<com.storlead.web.model.vo.CorpWeChatDeptVO>
     * @author blank
     * @date 2021-3-9 下午 12:03
     */
    public static List<CorpWeChatDeptVO> getDeptListFormTencent(@NotNull String url, @NotNull String accessToken, Long deptId) {
        if (deptId != null && deptId > 0) {
            url = url.replace("ID", deptId.toString());
        }
        String resultStr = HttpUtil.get(url.replace("ACCESS_TOKEN", accessToken));
        if (StringUtils.isNotEmpty(resultStr)) {
            log.debug("查询所有部门---> {}", resultStr);
            JSONObject jsonResult = new JSONObject(resultStr);
            int errCode = jsonResult.getInt("errcode");
            String errMsg = jsonResult.getStr("errmsg");
            if (CorpWeChatConstants.RETURN_SUCCESS_CODE == errCode) {
                log.info("部门 获取成功: {} ", jsonResult.getJSONArray("department").toString());
                return jsonResult.getJSONArray("department").toList(CorpWeChatDeptVO.class);
            }
        }
        return null;
    }

    /**
     * 获取部门成员详情
     *
     * @param url         https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID&fetch_child=FETCH_CHILD
     *                    参数	        必须	说明
     *                    access_token	是	调用接口凭证
     *                    department_id	是	获取的部门id
     *                    fetch_child	否	1/0：是否递归获取子部门下面的成员
     * @param accessToken accessToken
     * @param deptId      企业微信部门ID
     * @return java.util.List<com.storlead.web.model.vo.CorpWeChatUserVO>
     * @author blank
     * @date 2021-3-9 下午 12:19
     */
    public static List<CorpWeChatUserVO> getUserListUnderDeptFormTencent(@NotNull String url, @NotNull String accessToken, Long deptId) {
        if (deptId != null && deptId > 0) {
            url = url.replace("DEPARTMENT_ID", deptId.toString());
        }
        String resultStr = HttpUtil.get(url.replace("ACCESS_TOKEN", accessToken).replace("FETCH_CHILD", "1")+"&debug=1");
        if (StringUtils.isNotEmpty(resultStr)) {
            log.debug("查询所有用户---> {}", resultStr);
            JSONObject jsonResult = new JSONObject(resultStr);
            int errCode = jsonResult.getInt("errcode");
            String errMsg = jsonResult.getStr("errmsg");
            if (CorpWeChatConstants.RETURN_SUCCESS_CODE == errCode) {
                log.info("用户 获取成功: {} ", jsonResult.getJSONArray("userlist").toString());
                String json = jsonResult.getJSONArray("userlist").toString();
                List<CorpWeChatUserVO> users = JSON.parseArray(json,CorpWeChatUserVO.class);
               // com.alibaba.fastjson.JSONObject.(json,List<CorpWeChatUserVO>)
                return users;
            }
        }
        return null;
    }

    public static String getWxUserIdByMobile(@NotNull String url, @NotNull String accessToken,String mobile) {
        Map<String,Object> parm = new HashMap();
        parm.put("mobile",mobile);
        String resultStr = HttpUtil.post(url.replace("ACCESS_TOKEN", accessToken),JSON.toJSONString(parm));
        if (StringUtils.isNotEmpty(resultStr)) {
            log.debug("查询所有用户---> {}", resultStr);
            JSONObject jsonResult = new JSONObject(resultStr);
            int errCode = jsonResult.getInt("errcode");
            String errMsg = jsonResult.getStr("errmsg");
            if (CorpWeChatConstants.RETURN_SUCCESS_CODE == errCode) {
                String userid = jsonResult.getStr("userid").toString();
                // com.alibaba.fastjson.JSONObject.(json,List<CorpWeChatUserVO>)
                return userid;
            }
        }
        return null;
    }

    /**
     * 获取员工打卡数据
     * @param url
     * @param accessToken
     * @param useridlist
     * @return
     */
    public static List<SummaryInfoVO> getUserCheckinDayData(@NotNull String url, @NotNull String accessToken, List<String> useridlist) {

        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("starttime","1599062400");
        paramMap.put("endtime","1599062400");
        paramMap.put("useridlist",useridlist);

        String resultStr = HttpUtil.post(url.replace("ACCESS_TOKEN", accessToken),paramMap);
        if (StringUtils.isNotEmpty(resultStr)) {
            log.debug("查询所有用户---> {}", resultStr);
            JSONObject jsonResult = new JSONObject(resultStr);
            int errCode = jsonResult.getInt("errcode");
            String errMsg = jsonResult.getStr("errmsg");
            if (CorpWeChatConstants.RETURN_SUCCESS_CODE == errCode) {
                log.info("获取打开信息: {} ", jsonResult.getJSONArray("userlist").toString());
                String json = jsonResult.getJSONArray("userlist").toString();
                List<SummaryInfoVO> infos = JSON.parseArray(json,SummaryInfoVO.class);
                // com.alibaba.fastjson.JSONObject.(json,List<CorpWeChatUserVO>)
                return infos;
            }
        }
        return null;
    }

    /**
     * 获取访问用户身份
     *
     * @param url         https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE
     *                    参数	        必须	说明
     *                    access_token	是	调用接口凭证
     *                    code	        是	通过成员授权获取到的code，最大为512字节。每次成员授权带上的code将不一样，code只能使用一次，5分钟未被使用自动过期。
     * @param accessToken accessToken
     * @param code        扫码后返回的code
     * @return UserId 用户表 企业微信用户ID
     * @author blank
     * @date 2021-3-9 下午 5:11
     */
    public static String getScanUserId(@NotNull String url, @NotNull String accessToken, @NotNull String code) {

        String resultStr = HttpUtil.get(url.replace("ACCESS_TOKEN", accessToken).replace("CODE", code));
        if (StringUtils.isNotEmpty(resultStr)) {
            log.debug("获取访问用户身份---> {}", resultStr);
            JSONObject jsonResult = new JSONObject(resultStr);
            int errCode = jsonResult.getInt("errcode");
            String errMsg = jsonResult.getStr("errmsg");
            if (CorpWeChatConstants.RETURN_SUCCESS_CODE == errCode) {
                log.info("获取访问用户身份 获取成功: {} ", jsonResult.toString());
                return jsonResult.getStr("UserId");
            }
        }

        return null;

    }

    /**
     * 发送信息
     * POST       https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN
     * 用户或部门不可同时为空
     *
     * @param accessToken accessToken
     * @param agentId     应用ID
     * @param content     文本内容
     * @param toUser      "userid1|userid2"
     * @param toDept      "deptId1|deptId2"
     * @return boolean
     * @author blank
     * @date 2021-3-9 下午 3:20
     */
    public static boolean sendTextMsg(@NotNull String requestUrl, @NotNull String accessToken, @NotNull int agentId, @NotNull String content, Set<String> toUser, Set<Long> toDept) {
        requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken);
        JSONObject paramJson = new JSONObject();

        if (toUser != null && toUser.size() > 0) {
            paramJson.putOpt("touser", String.join("|", toUser));
        }
        if (toDept != null && toDept.size() > 0) {
            paramJson.putOpt("toparty", String.join("|", toDept.stream().map(Object::toString).collect(Collectors.toSet())));
        }
        paramJson.putOpt("agentid", agentId);
        //消息类型，此时固定为：text
        paramJson.putOpt("msgtype", "text");
        JSONObject textJson = new JSONObject();
        textJson.putOpt("content", content);
        paramJson.putOpt("text", textJson);
        String resultStr = HttpUtil.post(requestUrl, paramJson.toString());
        if (StringUtils.isNotEmpty(resultStr)) {
            log.debug("发送消息---> {}", resultStr);
            JSONObject jsonResult = new JSONObject(resultStr);
            int errCode = jsonResult.getInt("errcode");
            String errMsg = jsonResult.getStr("errmsg");
            if (CorpWeChatConstants.RETURN_SUCCESS_CODE == errCode) {
                log.info("发送信息成功: {} ", jsonResult.toString());
                return true;
            }
        }
        return false;

    }

    /**
     * 发送卡片信息
     * POST       https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN
     * 用户或部门不可同时为空
     *
     * @param accessToken    accessToken
     * @param agentId        应用ID
     * @param title          卡片标题
     * @param description    卡片内容
     * @param redirectionUrl 点击卡片跳转URL
     * @param toUser         "userid1|userid2"
     * @param toDept         "deptId1|deptId2"
     * @return boolean
     * @author blank
     * @date 2021-3-9 下午 3:20
     */
    public static boolean sendTextCardMsg(@NotNull String requestUrl, @NotNull String accessToken, @NotNull int agentId, @NotNull String title, @NotNull String description, @NotNull String redirectionUrl, Set<String> toUser, Set<Long> toDept) {
        requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken);
        JSONObject paramJson = new JSONObject();

        if (toUser != null && toUser.size() > 0) {
            paramJson.putOpt("touser", String.join("|", toUser));
        }
        if (toDept != null && toDept.size() > 0) {
            paramJson.putOpt("toparty", String.join("|", toDept.stream().map(Object::toString).collect(Collectors.toSet())));
        }
        paramJson.putOpt("agentid", agentId);
        //消息类型，此时固定为：textcard
        paramJson.putOpt("msgtype", "textcard");
        JSONObject textcard = new JSONObject();
        textcard.putOpt("title", title);
        textcard.putOpt("description", description);
        textcard.putOpt("url", redirectionUrl);
        paramJson.putOpt("textcard", textcard);
        String resultStr = HttpUtil.post(requestUrl, paramJson.toString());
        if (StringUtils.isNotEmpty(resultStr)) {
            log.error("发送消息---> {}", resultStr);
            JSONObject jsonResult = new JSONObject(resultStr);
            int errCode = jsonResult.getInt("errcode");
            String errMsg = jsonResult.getStr("errmsg");
            if (CorpWeChatConstants.RETURN_SUCCESS_CODE == errCode) {
                log.info("发送信息成功: {} ", jsonResult.toString());
                return true;
            }
        }
        return false;

    }


    @SneakyThrows
    public static void main(String[] args) {

        //getAccessToken("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET", "ww5323bd8ab4394132", "oo-HU1MjI7_4rV_EuCwbCg02YOaciOAeYyfAtqfZnT4");
        String redirectUrl = URLEncoder.encode("https://okr.test.storlead.com","UTF8");
        Set<String> users = new HashSet<>();
        users.add("YangPeiZhi");
        users.add("ChenKaiQiang");
        sendTextCardMsg(
                "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN",
//                "bqc_0Q0Mpr3VNQKTRnmSnQDKq73_H40gh_J6Q8_lbwMjWHbyfytSYVztm2W9fzbdH84LnW57wJLk9mcI4zhMH1ZIal_ShWxknx6xlrHu6QkkXyNvoMHVJNO7Csu6bgy7TOsnk4cF-JAPWjFyLq7tsJTrkMhMsgJWp1b4shbdBoaivKIQZvb3liQjorTf5RZniUq3LWnMz98SDTd04EcZMQ",
                "2Q9ODUe0HNZ6UUbBskDUU4KQAwU0G7xNpazy_jTCk6ZeToFCeMBcBpe_etnI7d7vfdC-7oUQkw1dQwwl8_4Sphn8sG1BM5jTqe9aK5Tnahs2qcorUy1Y1X6elmemibEzAFV7icuDNZma-dUu7abWjn26tCntBivbKLW-ORR_i4g8Z-871iq6RN3A52rqZ2jaEBQdGapgcam57bYVoSTNlA",
                1000028,
                "目标管理测试2",
                "目标管理测试2",
                "https://open.weixin.qq.com/connect/oauth2/authorize?appid=ww5323bd8ab4394132&agentid=1000027&redirect_uri="+redirectUrl+"&response_type=code&scope=snsapi_base&state=go_to_my_salary#wechat_redirect",
                users,
                null
        );
    }
//    @SneakyThrows
//    public static void main(String[] args) {
//            String url ="https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET";
//            String corpId="ww5323bd8ab4394132";
//            String corpSecret="lZ9hTmmFnOhOtTuYfOXvVHj3pQzbvPMIoWA9Op3bFhc";
//        WechatToken accessToken = getAccessToken(url, corpId, corpSecret);
//        System.out.println(accessToken);
//
//    }

}
