package com.bcxin.message.service.messagecenter;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bcxin.message.common.emus.MsgSyncTimeTaskStatusEnum;
import com.bcxin.message.common.utils.DateUtil;
import com.bcxin.message.common.utils.IdGeneratorSnowflake;
import com.bcxin.message.dao.mapper.messagecenter.MsgSyncTimeTaskMapper;
import com.bcxin.message.dtos.yehuo.TMessagesResponse;
import com.bcxin.message.entity.messagecenter.MsgSyncTimeTaskEntity;
import com.bcxin.message.service.yehuo.TMessagesService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * description：消息中心-消息同步时间任务表 service
 * author：linchunpeng
 * date：2025/8/11
 */
@Slf4j
@Service
public class MsgSyncTimeTaskService extends ServiceImpl<MsgSyncTimeTaskMapper, MsgSyncTimeTaskEntity> {

    @Autowired
    private TMessagesService tMessagesService;
    @Autowired
    private MsgOrgEffectiveTimeService msgOrgEffectiveTimeService;
    @Autowired
    private MsgExpiredTimeService msgExpiredTimeService;
    @Autowired
    private IdGeneratorSnowflake snowflake;

    @Value("${message.create-msg-sync-time-task.time-interval}")
    private Integer timeInterval;

    @Transactional
    public void createMsgSyncTimeTask() {
        log.info("创建消息同步时间任务");
        Date nowTime = new Date();
        //取出最后一次任务
        LambdaQueryChainWrapper<MsgSyncTimeTaskEntity> lqw = this.lambdaQuery();
        lqw.orderByDesc(MsgSyncTimeTaskEntity::getCreateTime);
        lqw.last("limit 1");
        List<MsgSyncTimeTaskEntity> list = lqw.list();
        MsgSyncTimeTaskEntity lastTask = CollectionUtil.isNotEmpty(list) ? list.get(0) : null;
        log.info(lastTask == null ? "没有最近一次任务" : "最近一次的任务数据为：" + JSONObject.toJSONString(lastTask));
        //判断上次任务已完成
        if (lastTask != null && lastTask.getTaskStatus() != MsgSyncTimeTaskStatusEnum.SYNC_COMPLETE.getCode()) {
            //最近一次同步任务未完成
            log.info("最近一次同步任务未完成");
            int intervalHour = 2;
            //2个小时毫秒数
            long intervalTime = 1000 * 60 * 60 * intervalHour;

            long differenceTime = nowTime.getTime() - lastTask.getCreateTime().getTime();
            if (differenceTime >= intervalTime) {
                //最近一次任务的创建时间>2小时
                log.info("最近一次任务的创建时间>=2小时，进行补偿，复制一个任务出来，重新同步");
                lastTask.setTaskStatus(MsgSyncTimeTaskStatusEnum.SYNC_COMPLETE.getCode());
                lastTask.setSyncResult("创建时间>=2小时，进行补偿，复制一个任务出来，重新同步");
                lastTask.setUpdateTime(new Date());
                this.updateById(lastTask);
                //创建新任务
                newTask(nowTime, lastTask.getStartTime(), lastTask.getEndTime());
            } else {
                log.info("最近一次任务的创建时间与当前时间差：{} 毫秒，<{}小时，无需补偿", differenceTime, intervalHour);
            }
        } else {
            //最近一次同步任务已完成
            log.info("最近一次同步任务已完成 || 没有最近一次任务");
            Date syncBeginTime = DateUtil.getMinuteZeroTime(nowTime);
            //配置拉取间隔
            int after = timeInterval;
            //1个小时毫秒数
            long intervalTime = 1000 * 60 * 60;
            if (lastTask != null) {
                syncBeginTime = lastTask.getEndTime();
                if (nowTime.getTime() - syncBeginTime.getTime() > intervalTime) {
                    //最近一次任务的结束时间>1小时
                    log.info("最近一次任务的结束时间：{}，当前时间：{}，间隔>1小时，需要翻倍拉取", lastTask.getEndTime(), nowTime);
                    log.info("原本拉取：{}分钟", after);
                    after = after * 2;
                    log.info("现在拉取：{}分钟", after);
                }
            }

            Date syncEndTime = DateUtil.getAfterNumMinuteTime(syncBeginTime, after);
            log.info("新的任务拉取数据开始时间：{}，拉取数据开始时间：{}", DateUtil.formatDateTime(syncBeginTime), DateUtil.formatDateTime(syncEndTime));
            if (syncEndTime.getTime() >= nowTime.getTime()) {
                //新任务的结束时间 >= 当前时间，无法创建任务，等待下次定时任务启动
                log.info("新任务的结束时间 >= 当前时间，无法创建任务，等待下次定时任务启动");
            } else {
                //新任务的结束时间 < 当前时间
                log.info("新任务的结束时间 < 当前时间，可以创建新的任务");
                //创建新任务
                newTask(nowTime, syncBeginTime, syncEndTime);
            }
        }
    }


    /**
     * description：创建新任务
     * author：linchunpeng
     * date：2025/8/12
     */
    private void newTask(Date nowTime, Date syncBeginTime, Date syncEndTime) {
        MsgSyncTimeTaskEntity msgSyncTimeTaskEntity = new MsgSyncTimeTaskEntity();
        msgSyncTimeTaskEntity.setId(snowflake.snowflakeId());
        msgSyncTimeTaskEntity.setStartTime(syncBeginTime);
        msgSyncTimeTaskEntity.setEndTime(syncEndTime);
        msgSyncTimeTaskEntity.setTaskStatus(MsgSyncTimeTaskStatusEnum.INIT.getCode());
        msgSyncTimeTaskEntity.setCreateTime(nowTime);
        msgSyncTimeTaskEntity.setUpdateTime(nowTime);
        this.save(msgSyncTimeTaskEntity);
    }


    /**
     * description：获取初始化的任务
     * author：linchunpeng
     * date：2025/8/12
     */
    @Transactional
    public MsgSyncTimeTaskEntity getInitTask() {
        log.info("获取初始化的任务");
        LambdaQueryChainWrapper<MsgSyncTimeTaskEntity> lqw = this.lambdaQuery();
        lqw.eq(MsgSyncTimeTaskEntity::getTaskStatus, MsgSyncTimeTaskStatusEnum.INIT.getCode());
        lqw.orderByDesc(MsgSyncTimeTaskEntity::getCreateTime);
        lqw.last("limit 1");
        List<MsgSyncTimeTaskEntity> list = lqw.list();
        if (CollectionUtil.isNotEmpty(list)) {
            log.info("初始化的任务有值，修改为：开始同步");
            MsgSyncTimeTaskEntity initTask = list.get(0);
            this.lambdaUpdate()
                    .eq(MsgSyncTimeTaskEntity::getId, initTask.getId())
                    .set(MsgSyncTimeTaskEntity::getTaskStatus, MsgSyncTimeTaskStatusEnum.BEGIN_SYNC.getCode())
                    .set(MsgSyncTimeTaskEntity::getUpdateTime, new Date())
                    .update();

            initTask.setTaskStatus(MsgSyncTimeTaskStatusEnum.BEGIN_SYNC.getCode());
            initTask.setUpdateTime(new Date());
            return initTask;
        }
        log.info("没有初始化的任务");
        return null;
    }

    /**
     * description：开始同步消息过期时间
     * author：linchunpeng
     * date：2025/8/12
     */
    public Map<String, String> syncMsgTime(Date startTime, Date endTime) {
        String syncResult = "";
        int syncTotalCount = 0;
        log.info("开始同步消息过期时间，时间范围：{} ~ {}", DateUtil.formatDateTime(startTime), DateUtil.formatDateTime(endTime));
        List<TMessagesResponse> messageList = tMessagesService.getMessageListByParam(startTime, endTime);
        if (CollectionUtil.isNotEmpty(messageList)) {
            log.info("消息记录不为空，需要同步");
            syncTotalCount = messageList.size();
            int successCount = 0;
            int errorCount = 0;
            for (TMessagesResponse messages : messageList) {
                try {
                    msgExpiredTimeService.createMsgExpiredTimeRecord(messages.getMid(), messages.getNumber(), messages.getDt(),
                            this.getUserIdAndOrgIdAndEffectiveTimeByMessage(messages));
                    successCount++;
                } catch (Exception e) {
                    log.error("同步消息过期时间异常，{}", e.getMessage());
                    errorCount++;
                }
            }
            syncResult = String.format("同步完成，总数：%s，成功：%s，失败：%s", syncTotalCount, successCount, errorCount);
        } else {
            log.info("消息记录为空，不需要同步");
            syncResult = "消息记录为空，不需要同步";
        }

        Map<String, String> syncResultMap =  new HashMap<>();
        syncResultMap.put("syncResult", syncResult);
        syncResultMap.put("syncTotalCount", "" + syncTotalCount);
        return syncResultMap;
    }

    /**
     * description：通过消息，获取这条消息的有效期，一条消息，有发送者，有接收者，取两者最大值
     * author：linchunpeng
     * date：2025/8/14
     */
    private String getUserIdAndOrgIdAndEffectiveTimeByMessage(TMessagesResponse messages) {
        String result = "0;0;0";
        int resultEffectiveTime = 0;
        String userIds = messages.getAllUserId();
        if (StringUtils.isNotBlank(userIds)) {
            for (String userId : userIds.split(";")) {
                String orgIdAndEffectiveTime = msgOrgEffectiveTimeService.getOrgIdAndEffectiveTimeByUserId(userId);
                String[] split = orgIdAndEffectiveTime.split(";");
                int effectiveTime = Integer.parseInt(split[1]);
                if (resultEffectiveTime < effectiveTime) {
                    //取最大值
                    resultEffectiveTime = effectiveTime;
                    result = userId + ";" + orgIdAndEffectiveTime;
                }
            }
        }
        return result;
    }


    /**
     * description：同步任务完成
     * author：linchunpeng
     * date：2025/8/12
     */
    @Transactional
    public void setTaskComplete(MsgSyncTimeTaskEntity task, Map<String, String> syncResultMap) {
        log.info("同步任务完成");
        this.lambdaUpdate()
                .eq(MsgSyncTimeTaskEntity::getId, task.getId())
                .set(MsgSyncTimeTaskEntity::getSyncResult, syncResultMap.get("syncResult"))
                .set(MsgSyncTimeTaskEntity::getSyncTotalCount, Integer.parseInt(syncResultMap.get("syncTotalCount")))
                .set(MsgSyncTimeTaskEntity::getTaskStatus, MsgSyncTimeTaskStatusEnum.SYNC_COMPLETE.getCode())
                .set(MsgSyncTimeTaskEntity::getUpdateTime, new Date())
                .update();
    }
}
