package vip.xiaonuo.coldchain.modular.push.utils;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import vip.xiaonuo.coldchain.modular.push.config.PushConfigure;
import vip.xiaonuo.coldchain.modular.push.entity.WeChatUser;
import vip.xiaonuo.coldchain.modular.push.param.AlarmPushParam;
import vip.xiaonuo.coldchain.modular.push.param.AlarmRecoverPushParam;
import vip.xiaonuo.coldchain.modular.push.param.OfflinePushParam;
import vip.xiaonuo.coldchain.modular.push.param.OnlinePushParam;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 推送类
 */
@Slf4j
public class PushUtil {
    private final static String ACCESS_TOKEN = "access_token";
    private final static String OPEN_ID = "openid";
    private final static String NICK_NAME = "nickname";
    private final static String SEX = "sex";
    private final static String HEAD_IMG_URL = "headimgurl";
    private final static String PROVINCE = "province";
    private final static String CITY = "city";
    private final static String COUNTRY = "country";
    private final static String PRIVILEGE = "privilege";
    private final static String UNION_ID = "unionid";

    private static WxMpConfigStorage wxMpConfigStorage() {
        WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
        config.setAppId(PushConfigure.getAppId());
        config.setSecret(PushConfigure.getSecret());
        config.setUseStableAccessToken(true);
        return config;
    }

    /**
     * 设备告警推送
     */
    public static String alarmPush(AlarmPushParam pushParam) {
        WxMpTemplateMessage.MiniProgram miniProgram = getMiniProgram(pushParam.getUserIdList());

        if (Objects.isNull(miniProgram)) {
            return null;
        }

        //1，配置
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxMpConfigStorage());

        // 推送消息
        String pushCode = "";
        for (String userId : pushParam.getUserIdList()) {
            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .toUser(userId)
                    .templateId(PushConfigure.getAlarmsTemplateId())
                    .miniProgram(miniProgram)
                    .build();
            // 配置你的信息
            //设备名称
            if (StrUtil.isBlank(pushParam.getDeviceName())) {
                pushParam.setDeviceName(" ");
            }
            templateMessage.addData(new WxMpTemplateData("thing23", pushParam.getDeviceName()));
            //事件类型
            if (StrUtil.isBlank(pushParam.getType())) {
                pushParam.setType(" ");
            }
            templateMessage.addData(new WxMpTemplateData("thing8", pushParam.getType()));
            //告警值
            if (StrUtil.isBlank(pushParam.getValue())) {
                pushParam.setValue(" ");
            }
            templateMessage.addData(new WxMpTemplateData("character_string28", pushParam.getValue()));
            //异常原因
            if (StrUtil.isBlank(pushParam.getContext())) {
                pushParam.setContext(" ");
            }
            templateMessage.addData(new WxMpTemplateData("thing25", pushParam.getContext()));
            //告警时间
            if (Objects.isNull(pushParam.getNoticeTime())) {
                pushParam.setNoticeTime(new Date());
            }
            String dateFormat = DateUtil.format(pushParam.getNoticeTime(), "yyyy-MM-dd HH:mm:ss");
            templateMessage.addData(new WxMpTemplateData("time3", dateFormat));

            try {
                pushCode = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return pushCode;
    }

    /**
     * 预警恢复消息推送
     */
    public static String alarmRecoverPush(AlarmRecoverPushParam pushParam) {
        WxMpTemplateMessage.MiniProgram miniProgram = getMiniProgram(pushParam.getUserIdList());

        if (Objects.isNull(miniProgram)) {
            return null;
        }

        //1，配置
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxMpConfigStorage());

        // 推送消息
        String pushCode = "";
        for (String userId : pushParam.getUserIdList()) {
            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .toUser(userId)
                    .templateId(PushConfigure.getAlarmsRecoverTemplateId())
                    .miniProgram(miniProgram)
                    .build();
            // 配置你的信息
            //设备名
            if (StrUtil.isBlank(pushParam.getDeviceName())) {
                pushParam.setDeviceName(" ");
            }
            templateMessage.addData(new WxMpTemplateData("thing15", pushParam.getDeviceName()));
            //告警时间
            if (Objects.isNull(pushParam.getAlarmTime())) {
                pushParam.setAlarmTime(new Date());
            }
            String alarmTimeFormat = DateUtil.format(pushParam.getAlarmTime(), "yyyy-MM-dd HH:mm:ss");
            templateMessage.addData(new WxMpTemplateData("time5", alarmTimeFormat));
            //告警原因
            if (StrUtil.isBlank(pushParam.getAlarmCause())) {
                pushParam.setAlarmCause(" ");
            }
            templateMessage.addData(new WxMpTemplateData("thing8", pushParam.getAlarmCause()));
            //恢复时间
            if (Objects.isNull(pushParam.getRecoverTime())) {
                pushParam.setRecoverTime(new Date());
            }
            String recoverTimeFormat = DateUtil.format(pushParam.getRecoverTime(), "yyyy-MM-dd HH:mm:ss");
            templateMessage.addData(new WxMpTemplateData("time6", recoverTimeFormat));
            //恢复原因
            if (StrUtil.isBlank(pushParam.getRecoverCause())) {
                pushParam.setRecoverCause(" ");
            }
            templateMessage.addData(new WxMpTemplateData("time3", pushParam.getRecoverCause()));

            try {
                pushCode = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return pushCode;
    }

    /**
     * 设备上线消息推送
     */
    public static String onlinePush(OnlinePushParam pushParam) {
        WxMpTemplateMessage.MiniProgram miniProgram = getMiniProgram(pushParam.getUserIdList());

        if (Objects.isNull(miniProgram)) {
            return null;
        }

        //1，配置
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxMpConfigStorage());

        // 推送消息
        String pushCode = "";
        for (String userId : pushParam.getUserIdList()) {
            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .toUser(userId)
                    .templateId(PushConfigure.getOnlineTemplateId())
                    .miniProgram(miniProgram)
                    .build();
            // 配置你的信息
            //设备名
            if (StrUtil.isBlank(pushParam.getDeviceName())) {
                pushParam.setDeviceName(" ");
            }
            templateMessage.addData(new WxMpTemplateData("thing2", pushParam.getDeviceName()));
            //设备状态
            if (StrUtil.isBlank(pushParam.getStatus())) {
                pushParam.setStatus(" ");
            }
            templateMessage.addData(new WxMpTemplateData("phrases3", pushParam.getStatus()));
            //设备位置
            if (StrUtil.isBlank(pushParam.getLocation())) {
                pushParam.setLocation(" ");
            }
            templateMessage.addData(new WxMpTemplateData("thing8", pushParam.getLocation()));
            //上线时间
            if (Objects.isNull(pushParam.getOnlineTime())) {
                pushParam.setOnlineTime(new Date());
            }
            String onlineTimeFormat = DateUtil.format(pushParam.getOnlineTime(), "yyyy-MM-dd HH:mm:ss");
            templateMessage.addData(new WxMpTemplateData("time6", onlineTimeFormat));

            try {
                pushCode = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return pushCode;
    }

    /**
     * 设备上线消息推送
     */
    public static String onlinePush(OfflinePushParam pushParam) {
        WxMpTemplateMessage.MiniProgram miniProgram = getMiniProgram(pushParam.getUserIdList());

        if (Objects.isNull(miniProgram)) {
            return null;
        }

        //1，配置
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxMpConfigStorage());

        // 推送消息
        String pushCode = "";
        for (String userId : pushParam.getUserIdList()) {
            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .toUser(userId)
                    .templateId(PushConfigure.getOfflineTemplateId())
                    .miniProgram(miniProgram)
                    .build();
            // 配置你的信息
            //设备名
            if (StrUtil.isBlank(pushParam.getDeviceName())) {
                pushParam.setDeviceName(" ");
            }
            templateMessage.addData(new WxMpTemplateData("thing2", pushParam.getDeviceName()));
            //设备状态
            if (StrUtil.isBlank(pushParam.getStatus())) {
                pushParam.setStatus(" ");
            }
            templateMessage.addData(new WxMpTemplateData("phrases3", pushParam.getStatus()));
            //设备位置
            if (StrUtil.isBlank(pushParam.getLocation())) {
                pushParam.setLocation(" ");
            }
            templateMessage.addData(new WxMpTemplateData("thing17", pushParam.getLocation()));
            //上线时间
            if (Objects.isNull(pushParam.getOfflineTime())) {
                pushParam.setOfflineTime(new Date());
            }
            String onlineTimeFormat = DateUtil.format(pushParam.getOfflineTime(), "yyyy-MM-dd HH:mm:ss");
            templateMessage.addData(new WxMpTemplateData("time4", onlineTimeFormat));

            try {
                pushCode = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return pushCode;
    }


    private static WxMpTemplateMessage.MiniProgram getMiniProgram(Set<String> userIdList) {
        // 数据校验
        if (Objects.isNull(userIdList) || userIdList.isEmpty()) {
            return null;
        }
        WxMpTemplateMessage.MiniProgram miniProgram = new WxMpTemplateMessage.MiniProgram();
        String miniProgramAppId = PushConfigure.getMiniProgram();
        miniProgram.setAppid(miniProgramAppId);//小程序appid
        miniProgram.setUsePath(false);
        miniProgram.setPagePath(PushConfigure.getPagePath());//用户点击时需要跳转的小程序页面
        return miniProgram;
    }


    public static WeChatUser getUserInfo(String code) {
        Map<?, ?> result = WeChatUtil.getAccessToken(code);
        String accessToken = result.get(ACCESS_TOKEN).toString();
        String openid = result.get(OPEN_ID).toString();
        String userInfoJsom = WeChatUtil.getUserInfo(accessToken, openid);
        log.info("用户授权获取信息：{}", userInfoJsom);
        Assert.notEmpty(userInfoJsom, "获取用户信息失败");

        // 解析JSON数据
        JSONObject jsonObject = new JSONObject(userInfoJsom);

        // 设置相关实体属性
        WeChatUser weChatUser = new WeChatUser();
        weChatUser.setAccessToken(accessToken);
        weChatUser.setCreateDate(LocalDateTime.now());
        weChatUser.setUpdateDate(LocalDateTime.now());
        weChatUser.setOpenid(openid);
        weChatUser.setNickname(jsonObject.getStr(NICK_NAME));
        weChatUser.setSex(jsonObject.getStr(SEX));
        weChatUser.setAvatar(jsonObject.getStr(HEAD_IMG_URL));
        weChatUser.setProvince(jsonObject.getStr(PROVINCE));
        weChatUser.setCity(jsonObject.getStr(CITY));
        weChatUser.setCountry(jsonObject.getStr(COUNTRY));
        weChatUser.setPrivilege(jsonObject.getStr(PRIVILEGE));
        weChatUser.setUnionid(jsonObject.getStr(UNION_ID));
        return weChatUser;
    }
}
