package com.xinelu.mobile.service.wechatappletcallback.impl;

import com.xinelu.common.config.WeChatAppletChatConfig;
import com.xinelu.common.enums.SubscribeMessageTypeEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.DateUtils;
import com.xinelu.manage.domain.residentinfo.ResidentInfo;
import com.xinelu.manage.domain.subscribemessagerecord.SubscribeMessageRecord;
import com.xinelu.manage.domain.subscribemessagesendrecord.SubscribeMessageSendRecord;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.subscribemessagerecord.SubscribeMessageRecordMapper;
import com.xinelu.manage.mapper.subscribemessagesendrecord.SubscribeMessageSendRecordMapper;
import com.xinelu.mobile.service.wechatappletcallback.WeChatAppletCallBackService;
import com.xinelu.mobile.vo.wechatappletcallback.WeChatMessagePushVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description 微信小程序事件回调业务层实现类
 * @Author 纪寒
 * @Date 2024-03-19 17:13:06
 * @Version 1.0
 */
@Service
@Slf4j
public class WeChatAppletCallBackServiceImpl implements WeChatAppletCallBackService {

    @Resource
    private SubscribeMessageRecordMapper subscribeMessageRecordMapper;
    @Resource
    private WeChatAppletChatConfig appletChatConfig;
    @Resource
    private PatientInfoMapper patientInfoMapper;
    @Resource
    private SubscribeMessageSendRecordMapper subscribeMessageSendRecordMapper;
    /**
     * 微信消息推送变更事件标识
     */
    private static final String SUBSCRIBE_MSG_CHANGE_EVENT = "subscribe_msg_change_event";

    /**
     * 微信消息推送订阅事件标识
     */
    private static final String SUBSCRIBE_MSG_POPUP_EVENT = "subscribe_msg_popup_event";

    /**
     * 微信消息推送发送结果事件标识
     */
    private static final String SUBSCRIBE_MSG__SENT_EVENT = "subscribe_msg_sent_event";

    /**
     * 微信小程序消息推送事件回调POST处理
     *
     * @param weChatMessagePushVO 请求参数
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void handleWeChatAppletCallBack(WeChatMessagePushVO weChatMessagePushVO) {
        if (weChatMessagePushVO.getEvent().equals(SUBSCRIBE_MSG_POPUP_EVENT)) {
            //处理用户订阅授权事件
            this.handleSubscribeMsgPopupEvent(weChatMessagePushVO);
        }
        if (weChatMessagePushVO.getEvent().equals(SUBSCRIBE_MSG_CHANGE_EVENT)) {
            //处理订阅消息变更事件
            this.handleSubscribeMsgChangeEvent(weChatMessagePushVO);
        }
        if (weChatMessagePushVO.getEvent().equals(SUBSCRIBE_MSG__SENT_EVENT)) {
            //处理订阅消息发送结果事件
            this.handleSubscribeMsgSentEvent(weChatMessagePushVO);
        }
    }

    /**
     * 处理用户订阅授权事件
     *
     * @param weChatMessagePushVO 参数信息
     */
    private void handleSubscribeMsgPopupEvent(WeChatMessagePushVO weChatMessagePushVO) {
        //处理订阅消息授权事件
        if (Objects.isNull(weChatMessagePushVO.getSubscribeMsgPopupEvent()) || CollectionUtils.isEmpty(weChatMessagePushVO.getSubscribeMsgPopupEvent().getSubscribeMsgPopupEventList())) {
            return;
        }
        //查询用户信息表
        ResidentInfo residentInfo = patientInfoMapper.getPatientInfoByOpenId(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
        //组装数据
        List<SubscribeMessageRecord> subscribeMessageRecordList = createSubscribeMessageRecordList(residentInfo, weChatMessagePushVO, SUBSCRIBE_MSG_POPUP_EVENT);
        if (CollectionUtils.isEmpty(subscribeMessageRecordList)) {
            return;
        }
        //根据openid查询数据库原有的订阅消息记录
        SubscribeMessageRecord subscribeMessageRecord = new SubscribeMessageRecord();
        subscribeMessageRecord.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
        List<SubscribeMessageRecord> existMessageRecordList = subscribeMessageRecordMapper.selectSubscribeMessageRecordList(subscribeMessageRecord);
        List<SubscribeMessageRecord> subtractSubscribeList = new ArrayList<>(CollectionUtils.subtract(subscribeMessageRecordList, existMessageRecordList));
        if (CollectionUtils.isNotEmpty(subtractSubscribeList)) {
            //新增订阅记录信息
            int insertCount = subscribeMessageRecordMapper.insertSubscribeMessageRecordList(subtractSubscribeList);
            if (insertCount <= 0) {
                log.error("微信订阅消息回调，新增用户订阅消息记录失败，记录信息为：[{}]", subtractSubscribeList);
                throw new ServiceException("微信订阅消息回调，新增用户订阅消息记录失败！");
            }
        }
        List<SubscribeMessageRecord> intersectionSubscribeList = new ArrayList<>(CollectionUtils.intersection(subscribeMessageRecordList, existMessageRecordList));
        if (CollectionUtils.isNotEmpty(intersectionSubscribeList)) {
            //修改订阅信息状态
            for (SubscribeMessageRecord messageRecord : intersectionSubscribeList) {
                Long patientId = null;
//                if (Objects.nonNull(residentInfo) && Objects.nonNull(residentInfo.getId())) {
//                    patientId = residentInfo.getId();
//                }
                String openId = StringUtils.isBlank(messageRecord.getOpenid()) ? "" : messageRecord.getOpenid();
                String templateId = StringUtils.isBlank(messageRecord.getTemplateId()) ? "" : messageRecord.getTemplateId();
                String subscribeStatus = StringUtils.isBlank(messageRecord.getSubscribeStatus()) ? "" : messageRecord.getSubscribeStatus();
                subscribeMessageRecordMapper.updateSubscribeMessageTemplateId(openId, templateId, subscribeStatus, patientId);
            }
        }
    }

    /**
     * 处理订阅消息变更事件
     *
     * @param weChatMessagePushVO 信息
     */
    private void handleSubscribeMsgChangeEvent(WeChatMessagePushVO weChatMessagePushVO) {
        if (Objects.isNull(weChatMessagePushVO.getSubscribeMsgChangeEvent()) || CollectionUtils.isEmpty(weChatMessagePushVO.getSubscribeMsgChangeEvent().getSubscribeMsgPopupEventList())) {
            return;
        }
        //查询用户信息表
        ResidentInfo residentInfo = patientInfoMapper.getPatientInfoByOpenId(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
        //组装数据
        List<SubscribeMessageRecord> subscribeMessageRecordList = createSubscribeMessageRecordList(residentInfo, weChatMessagePushVO, SUBSCRIBE_MSG_CHANGE_EVENT);
        if (CollectionUtils.isEmpty(subscribeMessageRecordList)) {
            return;
        }
        //根据openid查询数据库原有的订阅消息记录
        SubscribeMessageRecord subscribeMessageRecord = new SubscribeMessageRecord();
        subscribeMessageRecord.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
        List<SubscribeMessageRecord> existMessageRecordList = subscribeMessageRecordMapper.selectSubscribeMessageRecordList(subscribeMessageRecord);
        List<SubscribeMessageRecord> intersectionSubscribeList = new ArrayList<>(CollectionUtils.intersection(subscribeMessageRecordList, existMessageRecordList));
        if (CollectionUtils.isNotEmpty(intersectionSubscribeList)) {
            //修改订阅信息状态
            for (SubscribeMessageRecord messageRecord : intersectionSubscribeList) {
                Long patientId = null;
//                if (Objects.nonNull(residentInfo) && Objects.nonNull(residentInfo.getId())) {
//                    patientId = residentInfo.getId();
//                }
                String openId = StringUtils.isBlank(messageRecord.getOpenid()) ? "" : messageRecord.getOpenid();
                String templateId = StringUtils.isBlank(messageRecord.getTemplateId()) ? "" : messageRecord.getTemplateId();
                String subscribeStatus = StringUtils.isBlank(messageRecord.getSubscribeStatus()) ? "" : messageRecord.getSubscribeStatus();
                subscribeMessageRecordMapper.updateSubscribeMessageTemplateId(openId, templateId, subscribeStatus, patientId);
            }
        }
    }

    /**
     * 处理订阅消息发送结果事件
     *
     * @param weChatMessagePushVO 信息
     */
    private void handleSubscribeMsgSentEvent(WeChatMessagePushVO weChatMessagePushVO) {
        if (Objects.isNull(weChatMessagePushVO.getSubscribeMsgSentEvent()) || CollectionUtils.isEmpty(weChatMessagePushVO.getSubscribeMsgSentEvent().getSubscribeMsgSentEventList())) {
            return;
        }
        //组装数据
        List<SubscribeMessageSendRecord> subscribeMessageSendRecordList = createSubscribeMessageSendRecordList(weChatMessagePushVO);
        if (CollectionUtils.isNotEmpty(subscribeMessageSendRecordList)) {
            int insertCount = subscribeMessageSendRecordMapper.insertSubscribeMessageSendRecordList(subscribeMessageSendRecordList);
            if (insertCount <= 0) {
                log.error("微信订阅消息回调，新增用户订阅消息发送记录失败，记录信息为：[{}]", subscribeMessageSendRecordList);
                throw new ServiceException("微信订阅消息回调，新增用户订阅消息发送记录失败！");
            }
        }
    }

    /**
     * 组装订阅消息数据
     *
     * @param residentInfo        会员用户信息
     * @param weChatMessagePushVO 微信请求参数信息
     * @param eventType           事件类型
     * @return List<SubscribeMessageRecord>
     */
    private List<SubscribeMessageRecord> createSubscribeMessageRecordList(ResidentInfo residentInfo, WeChatMessagePushVO weChatMessagePushVO, String eventType) {
        List<SubscribeMessageRecord> subscribeMessageRecordList = Lists.newArrayList();
        if (SUBSCRIBE_MSG_POPUP_EVENT.equals(eventType)) {
            subscribeMessageRecordList = weChatMessagePushVO.getSubscribeMsgPopupEvent().getSubscribeMsgPopupEventList().stream().filter(Objects::nonNull).map(item -> {
                SubscribeMessageRecord subscribe = new SubscribeMessageRecord();
//                if (Objects.nonNull(residentInfo) && Objects.nonNull(residentInfo.getId())) {
//                    subscribe.setPatientId(residentInfo.getId());
//                }
                //此处模板通知需要根据实际情况进行修改
                subscribe.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
                subscribe.setAppletId(StringUtils.isBlank(weChatMessagePushVO.getToUserName()) ? "" : weChatMessagePushVO.getToUserName());
                subscribe.setTemplateId(StringUtils.isBlank(item.getTemplateId()) ? "" : item.getTemplateId());
                if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getFollowTemplateId().equals(item.getTemplateId())) {
                    subscribe.setMessageType(SubscribeMessageTypeEnum.FOLLOW_MESSAGE_PUSH.getInfo());
                }
                subscribe.setSubscribeCount(1);
                subscribe.setSubscribeTime(StringUtils.isBlank(weChatMessagePushVO.getCreateTime()) ? null : DateUtils.timestampToLocalDateTime(Long.parseLong(weChatMessagePushVO.getCreateTime()) * 1000L));
                subscribe.setCreateTime(LocalDateTime.now());
                subscribe.setSubscribeStatus(StringUtils.isBlank(item.getSubscribeStatusString()) ? "" : item.getSubscribeStatusString());
                return subscribe;
            }).collect(Collectors.toList());
        }
        if (SUBSCRIBE_MSG_CHANGE_EVENT.equals(eventType)) {
            subscribeMessageRecordList = weChatMessagePushVO.getSubscribeMsgChangeEvent().getSubscribeMsgPopupEventList().stream().filter(Objects::nonNull).map(item -> {
                SubscribeMessageRecord subscribe = new SubscribeMessageRecord();
//                if (Objects.nonNull(residentInfo) && Objects.nonNull(residentInfo.getId())) {
//                    subscribe.setPatientId(residentInfo.getId());
//                }
                //此处模板通知需要根据实际情况进行修改
                subscribe.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
                subscribe.setAppletId(StringUtils.isBlank(weChatMessagePushVO.getToUserName()) ? "" : weChatMessagePushVO.getToUserName());
                subscribe.setTemplateId(StringUtils.isBlank(item.getTemplateId()) ? "" : item.getTemplateId());
                if (StringUtils.isNotBlank(item.getTemplateId()) && appletChatConfig.getFollowTemplateId().equals(item.getTemplateId())) {
                    subscribe.setMessageType(SubscribeMessageTypeEnum.FOLLOW_MESSAGE_PUSH.getInfo());
                }
                subscribe.setSubscribeCount(1);
                subscribe.setSubscribeTime(StringUtils.isBlank(weChatMessagePushVO.getCreateTime()) ? null : DateUtils.timestampToLocalDateTime(Long.parseLong(weChatMessagePushVO.getCreateTime()) * 1000L));
                subscribe.setCreateTime(LocalDateTime.now());
                subscribe.setSubscribeStatus(StringUtils.isBlank(item.getSubscribeStatusString()) ? "" : item.getSubscribeStatusString());
                return subscribe;
            }).collect(Collectors.toList());
        }
        return subscribeMessageRecordList;
    }

    /**
     * 组装订阅消息发送结果数据
     *
     * @param weChatMessagePushVO 微信请求参数信息
     * @return List<SubscribeMessageSendRecord>
     */
    private List<SubscribeMessageSendRecord> createSubscribeMessageSendRecordList(WeChatMessagePushVO weChatMessagePushVO) {
        return weChatMessagePushVO.getSubscribeMsgSentEvent().getSubscribeMsgSentEventList().stream().map(item -> {
            SubscribeMessageSendRecord sendRecord = new SubscribeMessageSendRecord();
            sendRecord.setOpenid(StringUtils.isBlank(weChatMessagePushVO.getFromUserName()) ? "" : weChatMessagePushVO.getFromUserName());
            sendRecord.setAppletId(StringUtils.isBlank(weChatMessagePushVO.getToUserName()) ? "" : weChatMessagePushVO.getToUserName());
            sendRecord.setTemplateId(StringUtils.isBlank(item.getTemplateId()) ? "" : item.getTemplateId());
            sendRecord.setMessageType(StringUtils.isBlank(weChatMessagePushVO.getMsgType()) ? "" : weChatMessagePushVO.getMsgType());
            sendRecord.setMsgId(StringUtils.isBlank(item.getMsgId()) ? "" : item.getMsgId());
            sendRecord.setSubscribeTime(StringUtils.isBlank(weChatMessagePushVO.getCreateTime()) ? null : DateUtils.timestampToLocalDateTime(Long.parseLong(weChatMessagePushVO.getCreateTime()) * 1000L));
            sendRecord.setCreateTime(LocalDateTime.now());
            sendRecord.setErrorStatus(StringUtils.isBlank(item.getErrorStatus()) ? "" : item.getErrorStatus());
            sendRecord.setErrorCode(StringUtils.isBlank(item.getErrorCode()) ? null : Integer.parseInt(item.getErrorCode()));
            return sendRecord;
        }).collect(Collectors.toList());
    }
}
