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

import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.service.base.ResponseDto;
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.constant.SweetConstant;
import com.liquidnet.service.sweet.entity.SweetWechatUser;
import com.liquidnet.service.sweet.utils.RedisDataUtils;
import com.liquidnet.service.sweet.vo.SweetRemindVo;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Set;

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

    @Value("${liquidnet.wechat.service.zhengzai.appid}")
    private String appid;
    @Value("${liquidnet.wechat.service.zhengzai.secret}")
    private String secret;
    @Value("${liquidnet.client.admin.h5Url}")
    private String h5Url;

    @Autowired
    private RedisDataUtils redisDataUtils;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RedisUtil redisUtil;

    public ResponseDto send(String templateId) {
        String redisKey = SweetConstant.REDIS_KEY_SWEET_REMIND_ALL;
        Set<String> keys = redisTemplate.keys(redisKey);
        if (!CollectionUtils.isEmpty(keys)) {
            for (String rkey : keys) {
                try {
                    SweetRemindVo remindInfo = (SweetRemindVo) redisUtil.get(rkey);
                    SweetWechatUser sweetWechatUser = redisDataUtils.getSweetWechatUser(remindInfo.getUnionId());
                    KylinPerformanceVo performanceVo = (KylinPerformanceVo) redisUtil.get(KylinRedisConst.PERFORMANCES.concat(remindInfo.getPerformancesId()));
                    if (null == sweetWechatUser) {
                        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();
//                    LocalDateTime newNowTime = nowTime.minusMinutes(5);
                    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);
                        redisDataUtils.delSweetRemind(remindInfo.getUnionId());
                        continue;
                    }
                    if (-1 == DateUtil.compareStrDay(nowTimeStr, sellTimeLocalNewStr)) { // 还没到售卖期
                        log.info("还没到售卖期：[nowTimeStr=[{}], [sellTimeLocalNewStr=[{}]",
                                nowTimeStr, sellTimeLocalNewStr);

                        continue;
                    }
                    // 发送模板消息接口
                    WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                            // 接收者openid
                            .toUser(sweetWechatUser.getOpenId())
                            // 模板id
                            .templateId(templateId)
                            // 模板跳转链接
                            .url(h5Url.concat("/#/ticket/detail?id=").concat(remindInfo.getPerformancesId()))
                            .build();
                    // 添加模板数据
                    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 = null;
                    try {
                        // 发送模板消息
                        WxMpConfigStorage wxMpConfig = wxMpConfig(appid, secret);
                        WxMpService wxMpService = wxMpService(wxMpConfig);
                        msgId = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
                        if (null != msgId) {
                            redisDataUtils.delSweetRemind(remindInfo.getUnionId());
                        }
                    } catch (WxErrorException e) {
                        log.error("小程序演出提醒消息发送异常", e);
                    }
                    log.info("发送成功：[msgId=[{}]", msgId);
                } catch (Exception e) {
                    log.error("小程序演出提醒消息处理异常", e);
                }
            }
        }
        return ResponseDto.success();
    }

    public ResponseDto sendMsg() {
        String templateId = "CNLDBZYQoDgTWudicx8WU81Jr9b6RyG9hmK4O0tpK-k";
        return send(templateId);
    }

    public void subscribeSend(SweetWechatUser sweetWechatUser) {
        String templateId = "y-j82V1TYhlTH1j8QscuDPcPQtNiDtENb7N5IZMBvqU";
        try {
            WxMpTemplateMessage templateMessage = getTemplateMessage(templateId, sweetWechatUser.getOpenId(), "");
            // 添加模板数据
            templateMessage.addData(new WxMpTemplateData("first", "感谢关注"))
                    .addData(new WxMpTemplateData("keyword1", "操作流程"))
                    .addData(new WxMpTemplateData("keyword2", "客服电话"))
                    .addData(new WxMpTemplateData("remark", "这里是备注"));
            String msgId = sendTmpMsg(templateMessage);
        } catch (Exception e) {
            log.error("关注模版消息处理异常", e);
        }
    }

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

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

    private WxMpConfigStorage wxMpConfig(String appId, String appSecret) {
        WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
        config.setAppId(appId);
        config.setSecret(appSecret);
        return config;
    }

    private WxMpService wxMpService(WxMpConfigStorage mpConfig) {
        WxMpService service = new WxMpServiceImpl();
        service.setWxMpConfigStorage(mpConfig);
        return service;
    }

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

    public boolean followStatus(String unionId) {
        SweetWechatUser sweetWechatUser = redisDataUtils.getSweetWechatUser(unionId);
        if (null != sweetWechatUser && !sweetWechatUser.getUnionId().isEmpty()) {
            return true;
        } else {
            return false;
        }
    }
}
