package cn.ysk.cashier.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.ysk.cashier.enums.ShopWxMsgTypeEnum;
import cn.ysk.cashier.mybatis.entity.TbShopMsgState;
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
import cn.ysk.cashier.mybatis.mapper.TbShopMsgStateMapper;
import cn.ysk.cashier.pojo.shop.TbShopInfo;
import cn.ysk.cashier.repository.shop.TbShopInfoRepository;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.*;

@Data
@Slf4j
@Component
public class WxAccountUtil {
    @Value("${wx.ysk.appId}")
    private String appId = "wx212769170d2c6b2a";
    @Value("${wx.ysk.secrete}")
    private String secrete = "8492a7e8d55bbb1b57f5c8276ea1add0";
    @Value("${wx.ysk.operationMsgTmpId}")
    private String operationMsgTmpId;
    @Value("${wx.ysk.warnMsgTmpId}")
    private String warnMsgTmpId;

    private final TbShopMsgStateMapper shopMsgStateMapper;
    private final TbShopInfoRepository shopInfoRepository;

    static LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();

    static {

        linkedHashMap.put("40001", "获取 access_token 时 AppSecret 错误，或者 access_token 无效。请开发者认真比对 AppSecret 的正确性，或查看是否正在为恰当的公众号调用接口");
        linkedHashMap.put("40003", "不合法的 OpenID ，请开发者确认 OpenID （该用户）是否已关注公众号，或是否是其他公众号的 OpenID");
        linkedHashMap.put("40014", "不合法的 access_token ，请开发者认真比对 access_token 的有效性（如是否过期），或查看是否正在为恰当的公众号调用接口");
        linkedHashMap.put("40037", "不合法的 template_id");
        linkedHashMap.put("43101", "用户未订阅消息");
        linkedHashMap.put("43107", "订阅消息能力封禁");
        linkedHashMap.put("43108", "并发下发消息给同一个粉丝");
        linkedHashMap.put("45168", "命中敏感词");
        linkedHashMap.put("47003", "参数错误");

    }

    public static void main(String[] args) {
//        sendStockWarnMsg("13213", "31123", "234", "ojC-S6n2DDlpj52iVMoiLL0Ry4HI");
    }

    public String getRadarQrCode(Integer shopId) {
        HashMap<String, Object> req = new HashMap<>();
        req.put("expire_seconds", 300);
        req.put("action_name", "QR_STR_SCENE");
        HashMap<Object, Object> actionInfo = new HashMap<>();
        HashMap<String, Object> scene = new HashMap<>();
        scene.put("scene_str", "msg" + shopId);
        actionInfo.put("scene", scene);
        req.put("action_info", actionInfo);
        log.info("开始获取公众号二维码, 请求数据: {}", req);
        String resp = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + getAccessToken(), JSONObject.toJSONString(req));
        JSONObject respInfo = JSONObject.parseObject(resp);
        log.warn("获取微信公众号二维码结束，响应: {}", resp);
        if (!respInfo.containsKey("url")) {
            log.warn("获取微信公众号二维码失败，响应: {}", resp);
            throw new RuntimeException(resp);
        }
        return respInfo.getString("url");
    }


    public String getAccessToken() {
        String resp = HttpUtil.get(StrUtil.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}", appId, secrete));
        JSONObject respInfo = JSONObject.parseObject(resp);
        if (!respInfo.containsKey("access_token")) {
            log.warn("公众号获取token失败, 响应内容: {}", resp);
            throw new RuntimeException(resp);
        }
        return respInfo.getString("access_token");
    }

    public JSONObject sendTemplateMsg(String templateId, String toUserOpenId, Map<String, Object> data) {
        log.info("开始发送微信模板消息， 接收用户openId: {}, 消息数据: {}", toUserOpenId, data);
        String accessToken = getAccessToken();

        JSONObject object1 = new JSONObject();

        object1.put("template_id", templateId);
        object1.put("touser", toUserOpenId);
        object1.put("data", data);

        String response = HttpRequest.post("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".concat(accessToken)).body(object1.toString()).execute().body();
        log.info("微信模板消息发送成功，响应内容:{}", response);
        JSONObject resObj = JSONObject.parseObject(response);
        if (ObjectUtil.isNotEmpty(resObj) && ObjectUtil.isNotNull(resObj) && "0".equals(resObj.get("errcode") + "")) {
            return resObj;
        }

        throw new RuntimeException(linkedHashMap.getOrDefault(resObj.get("errcode") + "", "未知错误"));
    }

    @Async
    public void sendOperationMsg(List<TbShopOpenId> openIds, String userName, String operationDesc) {
        openIds.forEach(item -> {
            Map<String, Object> data = new HashMap<String, Object>() {{
                put("thing19", new HashMap<String, Object>() {{
                    put("value", userName);
                }});
                put("thing8", new HashMap<String, Object>() {{
                    put("value", operationDesc);
                }});
                put("time21", new HashMap<String, Object>() {{
                    put("value", DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
                }});
            }};
            log.info("开始发送敏感操作消息， 接收用户openId: {}, 操作用户: {}, 操作描述: {}", item.getOpenId(), userName, operationDesc);
            try {
                sendTemplateMsg(operationMsgTmpId, item.getOpenId(), data);
            } catch (Exception e) {
                log.error("发送失败, openId: {}, 响应: {}", item.getOpenId(), e.getMessage());
            }
        });

    }


    public void sendStockMsg(String shopName, String productName, int stock, String openId, ShopWxMsgTypeEnum shopWxMsgTypeEnum, Integer shopId) {

        stock = Math.max(stock, 0);
        Integer finalStock = stock;
        Map<String, Object> data = new HashMap<String, Object>() {{
            put("thing22", new HashMap<String, Object>() {{
                put("value", shopName);
            }});
            put("thing4", new HashMap<String, Object>() {{
                put("value", productName);
            }});
            put("number5", new HashMap<String, Object>() {{
                put("value", finalStock);
            }});
        }};
        log.info("开始发送库存预警消息， 接收用户openId: {}, 消息数据: {}", openId, data);
        try {
            sendTemplateMsg(warnMsgTmpId, openId, data);
        } catch (Exception e) {
            log.error("发送失败, openId:{}, msg: {}", openId, e.getMessage());
        }

    }
}
