package com.fs.app.task;


import com.fs.app.taskService.SopLogsChatTaskService;
import com.fs.app.taskService.SopLogsTaskService;
import com.fs.qw.service.IQwExternalErrRetryService;
import com.fs.qw.service.IQwGroupMsgService;
import com.fs.qw.service.IQwWorkUserService;
import com.fs.sop.mapper.QwSopLogsMapper;
import com.fs.sop.service.IQwSopLogsService;
import com.fs.sop.service.IQwSopTagService;
import com.fs.sop.service.ISopUserLogsService;
import com.fs.sop.service.impl.QwSopLogsServiceImpl;
import com.fs.sop.service.impl.QwSopServiceImpl;
import com.fs.sop.vo.QwSopLogsDoSendListTVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Component
@Slf4j
public class qwTask {

    @Autowired
    private QwSopServiceImpl qwSopService;

    @Autowired
    private IQwSopLogsService iQwSopLogsService;

    @Autowired
    private QwSopLogsServiceImpl qwSopLogsService;

    @Autowired
    private IQwGroupMsgService qwGroupMsgService;

    @Autowired
    private ISopUserLogsService sopUserLogsService;

    @Autowired
    private SopLogsTaskService sopLogsTaskService;

    @Autowired
    private SopLogsChatTaskService sopLogsTaskChatService;

    @Autowired
    private IQwExternalErrRetryService errRetryService;

    @Autowired
    private IQwWorkUserService qwWorkUserService;

    @Autowired
    private QwSopLogsMapper qwSopLogsMapper;
    @Autowired
    private IQwSopTagService qwSopTagService;
    /**
    * 定时任务 将 qw_sop任务 符合条件的录入到sop_user_Logs(clickHouse)
    */

    @Scheduled(cron = "0 10 1 * * ?")
    public void qwCheckSopRuleTime()
    {
        qwSopService.checkSopRuleTime();
    }

    @Scheduled(cron = "0 0/20 * * * ?")
    public void addTag(){
        qwSopTagService.addTag();
    }
    /**
     * 根据营期生成sopLogs待发记录
     * @throws Exception
     */
    @Scheduled(cron = "0 5 * * * ?") // 每小时的第5分钟触发
    @Async
    public void selectSopUserLogsListByTime() throws Exception {
        // 获取当前时间
        LocalDateTime currentTime = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0);
        // 打印日志，确认时间
        log.info("任务实际执行时间: {}", currentTime);

        // 调用服务方法
        sopLogsTaskService.selectSopUserLogsListByTime(currentTime);
    }

    /**
     * 定时任务 将 clickHouse的sopUserLogsChat(营期表)按每1分钟的巡回
     */
    @Scheduled(cron = "5 0/1 * * * ?")
    public void selectChatSopUserLogsListByTime() throws Exception {
//        LocalDateTime today = LocalDateTime.now(); // 当前日期和时间
        LocalDateTime today = LocalDateTime.now().withSecond(0).withNano(0);

        sopLogsTaskChatService.createAiChatSopLogs(today);
    }





    /**
     * 定时 发送 通过调用 企业微信接口 发送的 SOP 群发消息
     */
    @Scheduled(cron = "0 15 0 * * ?")
    public void SendQwApiSopLogTimer(){
        log.info("zyp \n【企微官方接口群发开始】");
//        qwSopLogsService.checkQwSopLogs();
        LocalDate localDate = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0).toLocalDate();
        String date = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

        qwSopLogsService.createCorpMassSending(date);
    }

    /**
     * 定时获取 通过调用 企业微信接口 发送的 SOP 客户群发消息 的反馈结果
     */
    @Scheduled(cron = "0 0 7 * * ?")
    public void GetQwApiSopLogResultTimer(){
        qwSopLogsService.qwSopLogsResult();
    }

    /**
    * 定时群发API接口的 客户/群 群发
    */
    @Scheduled(cron = "0 0/10 * * * ?")
    public void sendQwGroupMsgTask(){
        qwGroupMsgService.qwGroupMsgTask();
    }
    /**
    * 定时发送转换消息
    */
    @Scheduled(cron = "0 0 8 * * ?")
//    @Scheduled(cron = "0/10 * * * * ?")
    public void sendQwBySop(){
        sopUserLogsService.sendQwBySop();
    }


    /**
    * 企业微信自动打标签/备注 没打上的 补偿机制
    */
    @Scheduled(cron = "0 0/3 * * * ?")
    public void qwExternalErrRetryTimer(){
        log.info("补偿机制开始");
        errRetryService.qwExternalErrRetryTimer();
    }


    /**
     * 同步完企微客户，然后对加微的数据信息筛选并上传给百度进行投流优化
     */
    @Scheduled(cron = "0 0 6 * * ?")
    public void bdUpload(){
        qwWorkUserService.uploadBd();
    }

    /**
     * 补发过期完课消息
     */
    @Scheduled(cron = "0 0 * * * ?")  // 每小时的第0分钟0秒执行
    public void updateQwSopLogsByCancel(){
        log.info("补发过期完课消息 - 定时任务开始");
        try {
            sopLogsTaskService.updateSopLogsByCancel();
            log.info("补发过期完课消息 - 定时任务成功完成");
        } catch (Exception e) {
            log.error("补发过期完课消息 - 定时任务执行失败", e);
        }
    }

    /**
    * 批量处理sop待发送记录中已过期得消息每8分钟执行一次
    */
    @Scheduled(cron = "0 0/8 * * * ?")
    public void batchProcessingExpiredMessages(){

        log.info("批量处理sop待发送记录中已过期的消息");
        try {
            // Step 1: 批量更新已过期的记录
            List<QwSopLogsDoSendListTVO> expireded = iQwSopLogsService.expiredMessagesByQwSopLogs();
            if (!expireded.isEmpty()) {
                processAndInsertQwSopLogs(expireded);
            }
            log.info("处理已过期 - 定时任务成功完成");
        } catch (Exception e) {
            log.error("处理已过期 - 定时任务执行失败", e);
        }
    }

    // 定义一个方法来批量处理插入逻辑，支持每 500 条数据一次的批量插入
    private void processAndInsertQwSopLogs(List<QwSopLogsDoSendListTVO> logsByJsApiNotExtId) {
        // 定义批量插入的大小
        int batchSize = 500;

        // 循环处理外部用户 ID，每次处理批量大小的子集
        for (int i = 0; i < logsByJsApiNotExtId.size(); i += batchSize) {

            int endIndex = Math.min(i + batchSize, logsByJsApiNotExtId.size());
            List<QwSopLogsDoSendListTVO> batchList = logsByJsApiNotExtId.subList(i, endIndex);  // 获取当前批次的子集

            // 直接使用批次数据进行批量更新，不需要额外的 List
            try {
                qwSopLogsMapper.batchUpdateQwSopLogsBySendTime(batchList);
            } catch (Exception e) {
                // 记录异常日志，方便后续排查问题
                log.error("批量更新数据时发生异常，处理的批次起始索引为: " + i, e);
            }
        }
    }

    /**
    * 定时清除 2天以前的sop任务记录 每天删除
    */
    @Scheduled(cron = "0 10 0 * * ?")
    public void deleteQwSopLogsByDate() {

        qwSopLogsMapper.deleteQwSopLogsByDate();

    }

}
