package cn.com.poc.ai_software_copyright.utils;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;

import cn.com.poc.common.config.DifyConfigProperties;
import cn.com.poc.common.service.impl.DifyChatServiceImpl;
import cn.com.poc.common.service.BizFileUploadRecordService;
import cn.com.poc.common.service.BosConfigService;
import cn.com.poc.common.utils.DocumentLoad;
import cn.com.poc.common.utils.FileUtils;
import cn.com.yict.framemax.core.exception.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @author alex.yao
 * @date 2026/1/9
 */
@Component
public class SoftwareCopyRightUtils {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private BosConfigService bosConfigService;

    @Resource
    private BizFileUploadRecordService bizFileUploadRecordService;

    @Resource
    private DifyConfigProperties difyConfigProperties;

    @Resource
    private DifyChatServiceImpl difyChatService;

    /**
     * 插件是否存在压缩文件，存在则下载并解压文件
     */
    public List<String> downloadAndUnzipPlugin(List<String> fileURLS) {
        if (CollectionUtils.isEmpty(fileURLS)) {
            return fileURLS;
        }

        CopyOnWriteArrayList<String> result = new CopyOnWriteArrayList<>();
        List<File> tempFilesToClean = new ArrayList<>(); // 记录需要清理的临时文件

        try {
            List<CompletableFuture<Void>> futures = new ArrayList<>();

            for (String fileURL : fileURLS) {
                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                    String fileName = bizFileUploadRecordService.getFileNameByFileUrl(fileURL);
                    boolean compressedFile = FileUtils.isCompressedFile(fileName);

                    if (compressedFile) {
                        File downloadedFile = DocumentLoad.downloadURLDocument(fileURL);
                        tempFilesToClean.add(downloadedFile); // 添加到待清理列表

                        List<File> files = null;
                        try {
                            files = FileUtils.unGzip(downloadedFile);
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                        processUnzippedFiles(files, result, tempFilesToClean);
                    } else {
                        result.add(fileURL);
                    }
                });
                futures.add(future);
            }

            // 等待所有任务完成
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                    .join(); // 这里会抛出异常，如果任何一个任务失败

            return result;
        } catch (Exception e) {
            // 清理所有临时文件
            cleanupTempFiles(tempFilesToClean);
            throw new BusinessException("处理插件文件时发生异常: " + e.getMessage(), e);
        } finally {
            // 确保临时文件被清理
            cleanupTempFiles(tempFilesToClean);
        }
    }

    private void processUnzippedFiles(List<File> files, CopyOnWriteArrayList<String> result,
                                      List<File> tempFilesToClean) {
        if (CollectionUtils.isEmpty(files)) {
            return;
        }
        List<CompletableFuture<Void>> futures = new ArrayList<>();
        for (File file : files) {
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                FileInputStream fileInputStream = null;
                try {
                    fileInputStream = new FileInputStream(file);
                    String upload = bosConfigService.upload(fileInputStream, file.getName(), null);
                    result.add(upload);
                    tempFilesToClean.add(file); // 添加到待清理列表，以便在外部统一清理
                } catch (IOException e) {
                    throw new RuntimeException("上传文件失败: " + e.getMessage(), e);
                } finally {
                    if (fileInputStream != null) {
                        try {
                            fileInputStream.close();
                        } catch (IOException e) {
                            // 记录日志但不抛出异常
                            logger.error("关闭文件流失败: " + e.getMessage());
                        }
                    }
                }
            });
            futures.add(future);
        }

        // 等待所有上传任务完成
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
    }

    /**
     * 清理临时文件
     */
    private void cleanupTempFiles(List<File> tempFiles) {
        for (File tempFile : tempFiles) {
            if (tempFile != null && tempFile.exists()) {
                try {
                    tempFile.delete();
                } catch (Exception e) {
                    System.err.println("删除临时文件失败: " + tempFile.getAbsolutePath() + ", 错误: " + e.getMessage());
                }
            }
        }
    }

    /**
     * 执行阻塞式聊天
     */
    public void executeBlockingChat(List<String> fileUrls, String question,
                                    Map<String, Object> data, String user, String apiKeyType) {
        String apiKey = difyConfigProperties.getApiKeys().get(apiKeyType);
        try {
            difyChatService.blockingChat(fileUrls, question, data, user, apiKey);
        } catch (Exception e) {
            logger.error("执行{}生成异常: {}", user, e.getMessage(), e);
            throw new BusinessException("执行" + user + "生成异常", e);
        }
    }
}

