package com.liquidnet.service.sweet.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.dto.vo.middle.KylinTicketTimesVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.sweet.config.WechatMaConfigure;
import com.liquidnet.service.sweet.config.WechatMpConfigure;
import com.liquidnet.service.sweet.entity.SweetRemind;
import com.liquidnet.service.sweet.entity.SweetWechatUser;
import com.liquidnet.service.sweet.mapper.SweetRemindMapper;
import com.liquidnet.service.sweet.param.SweetOpenSendMsgParam;
import com.liquidnet.service.sweet.utils.QueueUtils;
import com.liquidnet.service.sweet.utils.RedisDataUtils;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * <p>
 * 公众号模版消息 服务实现类
 * </p>
 *
 * @author liquidnet
 * @since 2021-07-27
 */
@Slf4j
@Service
public class SweetWechatTemplateServiceImpl {

    @Value("${liquidnet.client.admin.h5Url}")
    private String h5Url;

    @Value("${liquidnet.wechat.applet.zhengzai.appid}")
    private String appletAppid;

    @Autowired
    private RedisDataUtils redisDataUtils;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private QueueUtils queueUtils;

    @Autowired
    private SweetRemindMapper sweetRemindMapper;

    @Autowired
    WechatMpConfigure wechatMpConfigure;

    @Autowired
    WechatMaConfigure wechatMaConfigure;

    public ResponseDto openSendMsg(SweetOpenSendMsgParam param) {
        queueUtils.sendMsgByRedis(MQConst.SweetQueue.SWEET_TEMPLATE_MSG.getKey(),
                JsonUtils.toJson(param));
        return ResponseDto.success();
    }

    public ResponseDto sendRemindMsg() {
        // test
        /*WxMpTemplateMessage templateMessage = getTemplateMessage("CNLDBZYQoDgTWudicx8WU81Jr9b6RyG9hmK4O0tpK-k", "oUpkkuNe4yuVs77aaKFvuvpgNOSw", h5Url.concat("/#/ticket/detail?id=").concat("111"));
        templateMessage.addData(new WxMpTemplateData("first", "感谢支持"))
                .addData(new WxMpTemplateData("keyword1", "摩登天空"))
                .addData(new WxMpTemplateData("keyword2", "正在现场"))
                .addData(new WxMpTemplateData("keyword3", "北京"))
                .addData(new WxMpTemplateData("remark", "感谢支持正在现场"));
        String msgId = sendTmpMsg(templateMessage);*/
        // test end

        String templateId = "CNLDBZYQoDgTWudicx8WU81Jr9b6RyG9hmK4O0tpK-k";

        List<SweetRemind> sweetRemindList = sweetRemindMapper.selectList(
                Wrappers.lambdaQuery(SweetRemind.class)
                        .eq(SweetRemind::getIsPush, 1)
        );
        ArrayList<String> remindIdList = CollectionUtil.arrayListString();
        if (!CollectionUtils.isEmpty(sweetRemindList)) {
            for (SweetRemind remindInfo : sweetRemindList) {
                try {
                    String remindId = remindInfo.getRemindId();
                    SweetWechatUser sweetWechatUser = redisDataUtils.getSweetWechatUser(remindInfo.getUnionId());
                    KylinPerformanceVo performanceVo = (KylinPerformanceVo) redisUtil.get(KylinRedisConst.PERFORMANCES.concat(remindInfo.getPerformancesId()));
                    if (null == sweetWechatUser) {
                        remindIdList.add(remindId);
                        log.info("无用户数据：[UnionId=[{}]", remindInfo.getUnionId());
                        continue;
                    }
                    if (null == performanceVo) {
                        log.info("无演出数据：[getPerformancesId=[{}]", remindInfo.getPerformancesId());
                        continue;
                    }
                    KylinTicketTimesVo kylinTicketTimesVo = performanceVo.getTicketTimeList().get(0);

                    LocalDateTime nowTime = LocalDateTime.now();
                    String nowTimeStr = DateUtil.Formatter.yyyyMMddHHmmss.format(nowTime);
                    String sellTime = performanceVo.getSellTime();
                    LocalDateTime sellTimeLocal = LocalDateTime.parse(sellTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    LocalDateTime sellTimeLocalNew = sellTimeLocal.minusMinutes(5);
                    String sellTimeLocalNewStr = DateUtil.Formatter.yyyyMMddHHmmss.format(sellTimeLocalNew);

                    String stopSellTime = performanceVo.getStopSellTime();
                    if (1 == DateUtil.compareStrDay(nowTimeStr, stopSellTime)) { // 超过售卖期 不推 删redis
                        log.info("超过售卖期：[nowTimeStr=[{}], [stopSellTime=[{}]",
                                nowTimeStr, stopSellTime);
                        remindIdList.add(remindId);
                        continue;
                    }
                    if (-1 == DateUtil.compareStrDay(nowTimeStr, sellTimeLocalNewStr)) { // 还没到售卖期
                        log.info("还没到售卖期：[nowTimeStr=[{}], [sellTimeLocalNewStr=[{}]",
                                nowTimeStr, sellTimeLocalNewStr);
                        continue;
                    }
                    // 发送模板消息接口
                    WxMpTemplateMessage templateMessage = getTemplateMessage(templateId, sweetWechatUser.getOpenId(), h5Url.concat("/#/ticket/detail?id=").concat(remindInfo.getPerformancesId()));
                    // 添加模板数据
                    templateMessage.addData(new WxMpTemplateData("first", "您关注的演出即将开始售票"))
                            .addData(new WxMpTemplateData("keyword1", performanceVo.getTitle()))
                            .addData(new WxMpTemplateData("keyword2", kylinTicketTimesVo.getTitle()))
                            .addData(new WxMpTemplateData("keyword3", performanceVo.getFieldName()))
                            .addData(new WxMpTemplateData("remark", "点击这里跳转购票"));
                    String msgId = sendTmpMsg(templateMessage);
                    if (null != msgId) {
                        remindIdList.add(remindId);
                    }
                } catch (Exception e) {
                    log.error("小程序演出提醒消息处理异常", e);
                }
            }
            if (!CollectionUtils.isEmpty(remindIdList)) {
                SweetRemind remindUpdate = SweetRemind.getNew();
                remindUpdate.setIsPush(2);
                remindUpdate.setUpdatedAt(LocalDateTime.now());
                sweetRemindMapper.update(
                        remindUpdate,
                        Wrappers.lambdaUpdate(SweetRemind.class)
                                .in(SweetRemind::getRemindId, remindIdList)
                );
            }
        }
        return ResponseDto.success();
    }

    public void subscribeSend(WxMpService wxMpService, SweetWechatUser sweetWechatUser) {
        String zhengzaiAppId = wechatMpConfigure.getWxMpService(1).getWxMpConfigStorage().getAppId();
        String otherAppId = wxMpService.getWxMpConfigStorage().getAppId();
        if (zhengzaiAppId.equals(otherAppId)) {
            String templateId = "y-j82V1TYhlTH1j8QscuDPcPQtNiDtENb7N5IZMBvqU";
            try {
                String nowTime = DateUtil.getNowTime();
                if (DateUtil.compareStrDay(nowTime, "2021-08-14 10:00:00") == 1) {
                    WxMpTemplateMessage templateMessage = getTemplateMessage(templateId, sweetWechatUser.getOpenId(), appletAppid, "pages/webview?query=lottery");
                    // 添加模板数据
                    templateMessage.addData(new WxMpTemplateData("first", "感谢关注「正在现场」服务号。我们是草莓音乐节演出官方票务平台。"))
                            .addData(new WxMpTemplateData("keyword1", "您已成功关注「正在现场」服务号"))
                            .addData(new WxMpTemplateData("keyword2", "4006-310-750"))
                            .addData(new WxMpTemplateData("remark", "点击下方小程序，再次参与「草莓星球来的人」周边抽奖"));
                    String msgId = sendTmpMsg(templateMessage);
                } else {
                    WxMpTemplateMessage templateMessage = getTemplateMessage(templateId, sweetWechatUser.getOpenId(), "");
                    // 添加模板数据
                    templateMessage.addData(new WxMpTemplateData("first", "感谢关注「正在现场」服务号。我们是草莓音乐节演出官方票务平台。"))
                            .addData(new WxMpTemplateData("keyword1", "您已成功关注「正在现场」服务号"))
                            .addData(new WxMpTemplateData("keyword2", "4006-310-750"))
                            .addData(new WxMpTemplateData("remark", "随时查阅订单信息，第一时间获取演出开售提醒，更天天有福利，周周有惊喜！"));
                    String msgId = sendTmpMsg(templateMessage);
                }

            } catch (Exception e) {
                log.error("关注模版消息处理异常", e);
            }
        } else {
            log.info("不是正在, 不发模版消息");
        }
    }

    /**
     * 获取templateMessage
     *
     * @param templateId
     * @param openId
     * @param url
     * @return
     */
    private WxMpTemplateMessage getTemplateMessage(String templateId, String openId, String url) {
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                .toUser(openId) // 接收者openid
                .templateId(templateId) // 模板id
                .url(url) // 模板跳转链接
                .build();
        return templateMessage;
    }

    private WxMpTemplateMessage getTemplateMessage(String templateId, String openId, String appid, String pagePath) {
        //配置小程序信息
        WxMpTemplateMessage.MiniProgram miniProgram = new WxMpTemplateMessage.MiniProgram();
        miniProgram.setAppid(appid);//小程序appid
        miniProgram.setUsePath(false);//true的话需要前端配合处理跳转
        miniProgram.setPagePath(pagePath);//用户点击时需要跳转的小程序页面

        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                .toUser(openId) // 接收者openid
                .templateId(templateId) // 模板id
                .miniProgram(miniProgram) // 模板跳转链接
                .build();
        return templateMessage;
    }

    /**
     * 发送消息
     *
     * @param templateMessage
     * @return
     */
    private String sendTmpMsg(WxMpTemplateMessage templateMessage) {
        String msgId = null;
        try {
            // 发送模板消息
            WxMpService wxMpService = wechatMpConfigure.getWxMpService(1);
            log.info("sendTmpMsg-isAccessTokenExpired：[{}] ", wxMpService.getWxMpConfigStorage().isAccessTokenExpired());
            log.info("sendTmpMsg-getAccessToken：[{}] ", wxMpService.getWxMpConfigStorage().getAccessToken());
            msgId = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
            log.info("模版消息发送成功：[msgId=[{}]", msgId);
        } catch (WxErrorException e) {
            log.error("模版消息发送异常", e);
        }
        return msgId;
    }

    public ResponseDto remind(String openId, String unionId, String performancesId) {
        redisDataUtils.setSweetRemind(openId, unionId, performancesId);
        return ResponseDto.success();
    }

    public boolean followStatusStr(String unionId) {
        String str = redisDataUtils.getSweetWechatUserStr(unionId);

        if (null == str || str.isEmpty()) {
            redisDataUtils.setSweetWechatUserStr(unionId);
            return false;
        } else {
            return true;
        }
    }

    public boolean followStatus(String unionId, Integer type, String userId, String phone) {
        SweetWechatUser sweetWechatUser = null;
        if (null == type || type <= 1) {
            sweetWechatUser = redisDataUtils.getSweetWechatUser(unionId);
        } else if (type == 2) {
            sweetWechatUser = redisDataUtils.getSweetWechatUserModernsky(unionId);
        }

        if (null != sweetWechatUser && !sweetWechatUser.getUnionId().isEmpty()) {
            // 同步手机号
            String oldAdamUserId = sweetWechatUser.getAdamUserId();
            String oldAdamPhone = sweetWechatUser.getAdamPhone();
            if (null == oldAdamUserId) {
                oldAdamUserId = "";
            }
            if (null == oldAdamPhone) {
                oldAdamPhone = "";
            }
            if ((!phone.isEmpty() || !userId.isEmpty()) && (oldAdamUserId.isEmpty() || oldAdamPhone.isEmpty())) {
                if (phone.isEmpty()) {
                    phone = oldAdamPhone;
                } else {
                    redisDataUtils.setUnionIdByPhone(phone, unionId);
                }
                if (userId.isEmpty()) {
                    userId = oldAdamUserId;
                }
                sweetWechatUser.setAdamPhone(phone);
                sweetWechatUser.setAdamUserId(userId);
                if (null == type || type <= 1) {
                    redisDataUtils.setSweetWechatUser(sweetWechatUser);
                } else if (type == 2) {
                    redisDataUtils.setSweetWechatUserModernsky(sweetWechatUser);
                }

                LinkedList<String> sqls = CollectionUtil.linkedListString();
                LinkedList<Object[]> sqlsDataA = CollectionUtil.linkedListObjectArr();
                sqls.add(SqlMapping.get("sweet_user.update2"));
                LocalDateTime now = LocalDateTime.now();
                sqlsDataA.add(new Object[]{
                        userId, phone, now, unionId, type
                });
                queueUtils.sendMsgByRedis(MQConst.SweetQueue.SWEET_USER_INSERT_DRAW.getKey(),
                        SqlMapping.gets(sqls, sqlsDataA));
            }
            return true;
        } else {
            return false;
        }
    }

}
