package com.usky.system.service.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.redis.core.RedisHelper;
import com.usky.system.domain.MceMbuser;
import com.usky.system.mapper.MceMbuserMapper;
import com.usky.system.service.MceMbuserService;
import com.usky.system.constant.constant;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.system.service.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.client.RestTemplate;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 消息中心_移动端注册表 服务实现类
 * </p>
 *
 * @author han
 * @since 2024-05-06
 */
@Service
@Slf4j
public class MceMbuserServiceImpl extends AbstractCrudService<MceMbuserMapper, MceMbuser> implements MceMbuserService {

    @Autowired
    private RedisHelper redisHelper;

    public String getWeChatAccessToken() {
        try {
            // 微信公众号官方获取AccessToken
            RestTemplate restTemplate = new RestTemplate();
            String requestParams = String.format(constant.WE_CHAT_ACCESS_TOKEN_URL, constant.WE_CHAT_APP_ID, constant.WE_CHAT_SECRET);
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(requestParams, String.class);

            String accessToken = JSONObject.parseObject(responseEntity.getBody()).getString("access_token");
            log.info("we_chat_access_token: " + accessToken);

            return accessToken;
        } catch (Exception e) {
            log.info("异常信息:{}", e);
        }
        return null;
    }

    public static long getTimeDifference(String oldTime, String newTime) throws ParseException {

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long NTime = df.parse(newTime).getTime();
        // 从对象中拿到时间
        long OTime = df.parse(oldTime).getTime();
        long diff = (NTime - OTime) / 1000 / 60;
        return diff;
    }

    @Override
    public JSONObject sendWeChatMessage(@RequestBody SendWeChatMessageRequestVO requestVO) {

        String infoTitle = requestVO.getInfoTitle();
        String infoContent = requestVO.getInfoContent();
        Integer infoId = requestVO.getInfoId();
        String openId = requestVO.getOpenId();
        String infoType = requestVO.getInfoType();
        String infoTypeName = requestVO.getInfoTypeName();
        String oaType = requestVO.getOaType();
        // access_token时效校验，判断获取access_token获取时间是否超过有效时间，超过就调用更新，保证一直有效
        if (!redisHelper.hasKey("access_key")) {
            redisHelper.set("access_time", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            redisHelper.set("access_key", this.getWeChatAccessToken());
        } else {
            try {
                String accessTime = redisHelper.get("access_time").toString();
                String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                long i = getTimeDifference(accessTime, nowTime);
                // 大于115分钟
                if (i > 115) {
                    redisHelper.set("access_time", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    redisHelper.set("access_key", this.getWeChatAccessToken());
                }
            } catch (Exception e) {
                throw new BusinessException(e.getMessage());
            }

        }

        Object obj = redisHelper.get("access_key");
        if (obj == null) {
            log.error("消息接收id：" + requestVO.getInfoId() + "，token为空，发送微信服务号消息失败");
            return null;
        }

        String tUrl;
        String templateId = "";

        Map<String, TemplateData> data = new HashMap<>();
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        switch (requestVO.getInfoType()) {
            // 登录成功通知
            case "0":
                // 登录时间
                data.put("time3", new TemplateData(nowTime, "#173177"));
                // 登录账号 userName
                data.put("thing6", new TemplateData(requestVO.getUserName(), "#173177"));
                // 登录IP
                data.put("character_string8", new TemplateData(requestVO.getIpAddress(), "#173177"));
                // 登录地点
                data.put("thing9", new TemplateData(requestVO.getLoginAddress(), "#173177"));
                // 登录方式
                data.put("thing10", new TemplateData(requestVO.getLoginType(), "#173177"));
                // 设置公众号模板消息ID
                templateId = constant.WE_CHAT_LOGIN_TEMPLATE_ID;
                break;

            /* 通知公告&工作报告通知（工单已完成通知）
             * 工单标题{{thing9.DATA}}
             * 发起人{{thing8.DATA}}
             * 完成时间{{time12.DATA}}
             **/
            case "1":
                data.put("thing9", new TemplateData("通知公告-" + requestVO.getInfoContent(), "#173177"));
                data.put("thing8", new TemplateData(requestVO.getRealName(), "#173177"));
                data.put("time12", new TemplateData(nowTime, "#173177"));
                templateId = constant.WE_CHAT_WORK_TEMPLATE_ID;
                break;
            case "5":
                data.put("thing9", new TemplateData("报告提醒-" + requestVO.getInfoContent(), "#173177"));
                data.put("thing8", new TemplateData(requestVO.getRealName(), "#173177"));
                data.put("time12", new TemplateData(nowTime, "#173177"));
                // 设置公众号模板消息ID
                templateId = constant.WE_CHAT_WORK_TEMPLATE_ID;
                break;

            case "3":
                /* OA系统流程审批通知
                 * 流程名称{{thing7.DATA}}
                 * 审批节点{{thing8.DATA}}
                 * 发起人{{thing13.DATA}}
                 * 发起时间{{time10.DATA}}
                 * 审批结果{{const21.DATA}}
                 **/
                data.put("thing7", new TemplateData(requestVO.getProcessName(), "#173177"));
                data.put("thing8", new TemplateData(requestVO.getApprovalNode(), "#173177"));
                data.put("thing13", new TemplateData(requestVO.getRealName(), "#173177"));
                data.put("time10", new TemplateData(nowTime, "#173177"));
                data.put("const21", new TemplateData(requestVO.getApprovalResult(), "#173177"));

                // 设置公众号模板消息ID
                templateId = constant.WE_CHAT_OA_TEMPLATE_ID;
                break;

            case "2":
                TemplateMsgEntityVO messageVo = new TemplateMsgEntityVO();
                messageVo.setTTitle(infoTitle);
                messageVo.setTKeyword1(infoContent);
                messageVo.setTKeyword2(infoType);
                messageVo.setTKeyword3(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                messageVo.setTRemark(infoContent);
                /* 设备预警信息提醒
                 * {{first.DATA}}
                 * 设备号：{{keyword1.DATA}}
                 * 报警类型：{{keyword2.DATA}}
                 * 时间：{{keyword3.DATA}}
                 * 备注：{{remark.DATA}}
                 **/
                messageVo.setTemplateId(constant.WE_CHAT_TEMPLATE_ID);
                data.put("first", new TemplateData(messageVo.getTTitle(), "#44b549"));
                data.put("keyword1", new TemplateData(messageVo.getTKeyword1(), "#173177"));
                data.put("keyword2", new TemplateData(messageVo.getTKeyword2(), "#173177"));
                data.put("keyword3", new TemplateData(messageVo.getTKeyword3(), "#173177"));
                data.put("remark", new TemplateData(messageVo.getTRemark(), "#173177"));

                templateId = messageVo.getTemplateId();
                break;
            case "4":
                /* 设备预警信息提醒
                 * {{first.DATA}}
                 * 设备号：{{keyword1.DATA}}
                 * 报警类型：{{keyword2.DATA}}
                 * 时间：{{keyword3.DATA}}
                 * 备注：{{remark.DATA}}
                 **/
                data.put("first", new TemplateData(requestVO.getInfoTitle(), "#44b549"));
                data.put("keyword1", new TemplateData(requestVO.getDeviceId(), "#173177"));
                data.put("keyword2", new TemplateData(requestVO.getInfoContent(), "#173177"));
                data.put("keyword3", new TemplateData(requestVO.getAlarmTime(), "#173177"));
                data.put("remark", new TemplateData(requestVO.getRemark(), "#173177"));

                // 设置公众号模板消息ID
                templateId = constant.WE_CHAT_TEMPLATE_ID;
                break;
        }

        log.info("oaType：{}", oaType);
        // 回调地址
        if ("3".equals(requestVO.getInfoType())) {
            tUrl = String.format(constant.WE_CHAT_CUSTOMER_CALL_URL3, infoType, infoTypeName, infoId, oaType);
        } else if (Objects.nonNull(infoTypeName)) {
            tUrl = String.format(constant.WE_CHAT_CUSTOMER_CALL_URL, infoType, infoTypeName, infoId);
        } else {
            tUrl = String.format(constant.WE_CHAT_CUSTOMER_CALL_URL1, infoType, infoId);
        }

        String token = obj.toString();
        String requestUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;
        Map<String, Object> content = new HashMap<>();
        content.put("touser", openId);
        if (!"0".equals(requestVO.getInfoType())) {
            content.put("url", tUrl);
        }
        if (StringUtils.isNotBlank(templateId)) {
            content.put("template_id", templateId);
        }
        content.put("data", data);
        String resp = HttpUtil.post(requestUrl, JSONUtil.parseObj(content).toString());
        System.out.println(content.toString());
        System.out.println(JSONUtil.parseObj(content));
        JSONObject result = JSONObject.parseObject(resp);
        System.out.println("发送消息:" + resp);
        return result;
    }
}
