package com.cmeeting.service;

import com.cmeeting.dto.UserDTO;
import com.cmeeting.email.EmailSender;
import com.cmeeting.job.EmailPushTask;
import com.cmeeting.job.FileProcessTask;
import com.cmeeting.log.service.ProcessLogService;
import com.cmeeting.mapper.primary.MeetingInfoMapper;
import com.cmeeting.mapper.primary.MeetingRecordTemplateMapper;
import com.cmeeting.mapper.primary.UserIdMapper;
import com.cmeeting.util.MinioUtils;
import com.cmeeting.util.RedisUtils;
import com.cmeeting.util.UserAdminConfig;
import com.cmeeting.vo.TencentMeetingVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@Service
@Slf4j
public class FileProcessProducer {
    
    @Resource(name = "fileProcessExecutor")
    private ThreadPoolTaskExecutor fileProcessExecutor;
    @Resource(name = "emailProcessExecutor")
    private ThreadPoolTaskExecutor emailProcessExecutor;
    @Value("${aec.key}")
    public String aesKey;
    @Autowired
    private FileProcessCallbackHandler callbackHandler;
    @Value(value = "${llm.api-addr}")
    private String llmApiAddr;
    @Value(value = "${llm.api-model}")
    private String llmModel;
    @Value(value = "${llm.api-token}")
    private String llmToken;
    @Value(value = "${llm.api-max-tokens}")
    private Integer llmMaxTokens;
    @Value(value = "${tencent.base-save-path}")
    private String baseSavePath;
    @Value("${permission.applicationId}")
    public String applicationId;
    @Value("${permission.tenantId}")
    public String permTenantId;
    @Resource
    private MeetingInfoMapper meetingInfoMapper;
    @Resource
    private MeetingRecordTemplateMapper meetingRecordTemplateMapper;
    @Resource
    private MeetingRecordTemplateService meetingRecordTemplateService;
    @Resource
    private MeetTypeService meetTypeService;
    @Resource
    private UserIdMapper userIdMapper;
    @Resource
    private MinioUtils minioUtils;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private EmailSender emailSender;
    @Resource
    private ProcessLogService processLogService;
    @Resource
    private UserAdminConfig userAdminConfig;
    //中集知识库文件的预览访问路径前缀
    @Value("${userAdmin.file-download-path}")
    private String fileDownloadPath;

    /**
     * 批量提交生成纪要任务
     *
     * @param recordFiles     转录文件信息
     * @param authorizedUsers 模板授权的人员
     * @param tidWidRelations 腾会id企微id对应关系
     * @param finalRetry      是否为最终重试
     * @param finalRetry
     */
    public void submitBatchTasks(List<TencentMeetingVO.RecordFile> recordFiles, List<UserDTO.TemplateAuthorizedUserDTO> authorizedUsers, Map<String, String> tidWidRelations, Boolean finalRetry) {
        List<Future<?>> futures = new ArrayList<>();
        log.info("待处理会议数量: {}", recordFiles.size());
        for (TencentMeetingVO.RecordFile recordFile : recordFiles) {
            // 为每个URL创建任务
            FileProcessTask task = new FileProcessTask(
                    recordFile.getRecordFileIdList(),
                    recordFile.getMeetingRecordId(),
                    recordFile.getMeetingId(),
                    recordFile.getSubMeetingId(),
                    baseSavePath,
                    Collections.emptyMap(),
                    meetingInfoMapper,
                    minioUtils,
                    redisUtils,
                    emailSender,
                    meetingRecordTemplateMapper,
                    meetingRecordTemplateService,
                    meetTypeService,
                    userIdMapper,
                    llmApiAddr,
                    llmModel,
                    llmToken,
                    llmMaxTokens,
                    finalRetry,
                    processLogService,
                    authorizedUsers,
                    tidWidRelations,
                    userAdminConfig,
                    applicationId,
                    fileDownloadPath,
                    permTenantId,
                    aesKey
            );

            // 提交任务到线程池
            Future<?> future = fileProcessExecutor.submit(() -> {
                task.process();
                callbackHandler.onComplete(task); // 回调处理
            });

            futures.add(future);
        }

        // 可以添加一个监控线程来检查所有任务完成情况
        monitorTaskCompletion(futures);
    }

    // 批量提交邮箱推送重试任务
    public void submitEmailPushTasks(List<TencentMeetingVO.RecordFile> recordFiles, Map<String, String> tidWidRelations) {
        List<Future<?>> futures = new ArrayList<>();

        for (TencentMeetingVO.RecordFile recordFile : recordFiles) {
            // 为每个URL创建任务
            EmailPushTask task = new EmailPushTask(
                    recordFile.getMeetingRecordId(),
                    recordFile.getMeetingId(),
                    recordFile.getSubMeetingId(),
                    baseSavePath,
                    Collections.emptyMap(),
                    meetingInfoMapper,
                    minioUtils,
                    redisUtils,
                    emailSender,
                    meetingRecordTemplateMapper,
                    tidWidRelations,
                    aesKey
            );

            // 提交任务到线程池
            Future<?> future = emailProcessExecutor.submit(() -> {
                task.process();
            });

            futures.add(future);
        }

        // 可以添加一个监控线程来检查所有任务完成情况
        monitorTaskCompletion(futures);
    }

    private void monitorTaskCompletion(List<Future<?>> futures) {
        new Thread(() -> {
            for (Future<?> future : futures) {
                try {
                    future.get(); // 阻塞直到任务完成
                } catch (InterruptedException | ExecutionException e) {
                    log.error("任务执行异常", e);
                }
            }
            callbackHandler.onAllComplete(); // 所有任务完成回调
        }).start();
    }
}