/**
 * @ProjectName: 智慧评标-主观分助手
 * @Package: com.zhpb.gdyd_zhpb_zgf.service.impl
 * @ClassName: ComparisonServiceImpl
 * @Description: 供应商对比分析服务实现
 * @Author: 张志锋
 * @Date: 2025-11-04
 * @Version: 1.0
 * @Copyright: © 2025 智慧评标-主观分助手
 */
package com.zhpb.gdyd_zhpb_zgf.service.impl;

import com.zhpb.gdyd_zhpb_zgf.dto.ComparisonRequest;
import com.zhpb.gdyd_zhpb_zgf.context.ModelRequestContextHolder;
import com.zhpb.gdyd_zhpb_zgf.dto.ComparisonResponse;
import com.zhpb.gdyd_zhpb_zgf.entity.mysql.ComparisonTask;
import com.zhpb.gdyd_zhpb_zgf.entity.mysql.File;
import com.zhpb.gdyd_zhpb_zgf.entity.mysql.PromptTemplate;
import com.zhpb.gdyd_zhpb_zgf.repository.mysql.ComparisonTaskRepository;
import com.zhpb.gdyd_zhpb_zgf.repository.mysql.FileRepository;
import com.zhpb.gdyd_zhpb_zgf.service.AIModelService;
import com.zhpb.gdyd_zhpb_zgf.service.ComparisonAsyncService;
import com.zhpb.gdyd_zhpb_zgf.service.ComparisonService;
import com.zhpb.gdyd_zhpb_zgf.service.PromptTemplateService;
import com.zhpb.gdyd_zhpb_zgf.utils.HttpClientUtils;
import com.zhpb.gdyd_zhpb_zgf.utils.TaskStatusUtils;
import com.alibaba.fastjson2.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 供应商对比分析服务实现
 */
@Service
public class ComparisonServiceImpl implements ComparisonService {

    private static final Logger logger = LoggerFactory.getLogger(ComparisonServiceImpl.class);

    @Autowired
    private ComparisonTaskRepository comparisonTaskRepository;

    @Autowired
    private FileRepository fileRepository;

    @Autowired
    private PromptTemplateService promptTemplateService;

    @Autowired
    private AIModelService aiModelService;

    @Autowired
    private org.springframework.core.env.Environment environment;

    @Autowired
    private ComparisonAsyncService comparisonAsyncService;

    @Autowired
    private com.zhpb.gdyd_zhpb_zgf.repository.mysql.SupplierRepository supplierRepository;

    @Override
    public ComparisonResponse.VendorsData getProjectVendors(String projectId) {
        logger.info("获取项目供应商数据: projectId={}", projectId);

        ComparisonResponse.VendorsData result = new ComparisonResponse.VendorsData();
        List<ComparisonResponse.VendorInfo> vendors = new ArrayList<>();

        try {
            // 获取项目中的所有文件
            List<File> files = fileRepository.findByProjectId(projectId);
            logger.info("项目 {} 中共有 {} 个文件", projectId, files.size());

            // 按供应商分组
            Map<String, List<File>> filesBySupplier = files.stream()
                .filter(file -> file.getSupplierId() != null && !file.getSupplierId().trim().isEmpty())
                .collect(Collectors.groupingBy(File::getSupplierId));

            logger.info("按供应商分组后共有 {} 个供应商", filesBySupplier.size());

            // 为每个供应商构建信息
            for (Map.Entry<String, List<File>> entry : filesBySupplier.entrySet()) {
                String supplierId = entry.getKey();
                List<File> supplierFiles = entry.getValue();

                ComparisonResponse.VendorInfo vendorInfo = new ComparisonResponse.VendorInfo();
                vendorInfo.setVendorId(supplierId);

                // 直接从数据库查询供应商名称
                String supplierName = getSupplierNameFromDatabase(supplierId);
                vendorInfo.setVendorName(supplierName);
                vendorInfo.setVendorType("供应商");

                // 构建文件信息列表
                List<ComparisonResponse.FileInfo> fileInfos = supplierFiles.stream()
                    .map(this::convertToFileInfo)
                    .collect(Collectors.toList());

                vendorInfo.setFiles(fileInfos);
                vendors.add(vendorInfo);

                logger.debug("供应商 {} ({}) 有 {} 个文件", supplierName, supplierId, fileInfos.size());
            }

            result.setVendors(vendors);
            logger.info("成功获取 {} 个供应商的信息", vendors.size());

        } catch (Exception e) {
            logger.error("获取项目供应商数据失败", e);
            throw new RuntimeException("获取供应商数据失败: " + e.getMessage());
        }

        return result;
    }

    /**
     * 从数据库查询供应商名称
     * 如果供应商名称为空或不存在，则返回supplierId
     */
    private String getSupplierNameFromDatabase(String supplierId) {
        try {
            com.zhpb.gdyd_zhpb_zgf.entity.mysql.Supplier supplier = supplierRepository.findBySupplierId(supplierId);
            if (supplier != null && supplier.getSupplierName() != null && !supplier.getSupplierName().trim().isEmpty()) {
                return supplier.getSupplierName();
            }
        } catch (Exception e) {
            logger.warn("查询供应商名称失败: supplierId={}, error={}", supplierId, e.getMessage());
        }
        // 如果查不到或名称为空，返回supplierId
        return supplierId;
    }

    @Override
    @Transactional
    public ComparisonResponse.StartTaskData startComparison(ComparisonRequest request) {
        logger.info("启动供应商对比分析任务: projectId={}, userId={}, vendorCount={}, dimensionCount={}",
            request.getProjectId(), request.getUserId(), request.getVendorIds().size(), request.getDimensions().size());

        try {
            // 生成任务ID
            String taskId = "task-" + UUID.randomUUID().toString().replace("-", "").substring(0, 12);

            // 创建对比任务
            ComparisonTask task = new ComparisonTask();
            task.setTaskId(taskId);
            task.setProjectId(request.getProjectId());
            task.setUserId(request.getUserId());
            task.setVendorIds(JSON.toJSONString(request.getVendorIds()));
            task.setDimensions(JSON.toJSONString(request.getDimensions()));
            task.setStatus("pending");
            task.setProgress(0);

            // 保存任务
            ComparisonTask savedTask = comparisonTaskRepository.save(task);
            logger.info("对比分析任务已创建: taskId={}", taskId);

            // 使用事务同步机制，确保事务提交后再调用异步方法
            // 这解决了异步线程查询不到刚保存数据的问题
            org.springframework.transaction.support.TransactionSynchronizationManager.registerSynchronization(
                new org.springframework.transaction.support.TransactionSynchronization() {
                    @Override
                    public void afterCommit() {
                        logger.info("事务已提交，开始触发异步对比分析任务: taskId={}", taskId);
                        comparisonAsyncService.processComparisonAsync(taskId);
                    }
                });

            // 返回任务启动信息
            ComparisonResponse.StartTaskData result = new ComparisonResponse.StartTaskData();
            result.setTaskId(taskId);
            // 使用数据库中的实际状态
            result.setStatus(TaskStatusUtils.toChineseStatus(savedTask.getStatus()));
            result.setCreatedTime(savedTask.getCreateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));

            return result;

        } catch (Exception e) {
            logger.error("启动对比分析任务失败", e);
            throw new RuntimeException("启动对比分析任务失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(readOnly = true)
    public ComparisonResponse.TaskHistoryData getComparisonHistory(String projectId, String userId) {
        logger.info("获取对比任务历史: projectId={}, userId={}", projectId, userId);

        ComparisonResponse.TaskHistoryData result = new ComparisonResponse.TaskHistoryData();
        List<ComparisonResponse.TaskInfo> tasks = new ArrayList<>();

        try {
            List<ComparisonTask> comparisonTasks = comparisonTaskRepository
                .findByProjectIdAndUserIdOrderByCreateTimeDesc(projectId, userId);

            int totalTasks = comparisonTasks.size();
            for (int i = 0; i < totalTasks; i++) {
                ComparisonTask task = comparisonTasks.get(i);
                ComparisonResponse.TaskInfo taskInfo = new ComparisonResponse.TaskInfo();
                
                // 设置任务名称：对比任务N (最新的任务编号最大)
                taskInfo.setTaskName("对比任务" + (totalTasks - i));
                
                taskInfo.setTaskId(task.getTaskId());
                taskInfo.setProjectId(task.getProjectId());
                taskInfo.setUserId(task.getUserId());
                // 转换为中文状态
                taskInfo.setStatus(TaskStatusUtils.toChineseStatus(task.getStatus()));

                // 解析供应商ID和名称
                List<String> vendorNames = new ArrayList<>();
                try {
                    List<String> vendorIds = JSON.parseArray(task.getVendorIds(), String.class);
                    taskInfo.setVendorCount(vendorIds.size());
                    // 查询供应商真实名称
                    for (String vendorId : vendorIds) {
                        com.zhpb.gdyd_zhpb_zgf.entity.mysql.Supplier supplier = 
                            supplierRepository.findBySupplierId(vendorId);
                        if (supplier != null && supplier.getSupplierName() != null) {
                            vendorNames.add(supplier.getSupplierName());
                        } else {
                            // 如果查不到供应商，使用vendorId作为备用
                            vendorNames.add(vendorId);
                        }
                    }
                } catch (Exception e) {
                    taskInfo.setVendorCount(0);
                }
                taskInfo.setVendors(vendorNames);

                // 解析维度
                List<String> dimensionNames = new ArrayList<>();
                try {
                    List<ComparisonRequest.ComparisonDimension> dimensions =
                        JSON.parseArray(task.getDimensions(), ComparisonRequest.ComparisonDimension.class);
                    taskInfo.setDimensionCount(dimensions.size());
                    // 提取维度名称
                    dimensionNames = dimensions.stream()
                        .map(ComparisonRequest.ComparisonDimension::getValue)
                        .collect(Collectors.toList());
                } catch (Exception e) {
                    taskInfo.setDimensionCount(0);
                }
                taskInfo.setDimensions(dimensionNames);

                taskInfo.setCreatedTime(task.getCreateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
                if (task.getCompletedTime() != null) {
                    taskInfo.setCompletedTime(task.getCompletedTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
                    // 计算耗时（秒）
                    long timeInSeconds = java.time.Duration.between(
                        task.getCreateTime(), task.getCompletedTime()).getSeconds();
                    taskInfo.setTime(timeInSeconds);
                }

                tasks.add(taskInfo);
            }

            result.setTasks(tasks);
            logger.info("成功获取 {} 个对比任务的历史记录", tasks.size());

        } catch (Exception e) {
            logger.error("获取对比任务历史失败", e);
            throw new RuntimeException("获取对比任务历史失败: " + e.getMessage());
        }

        return result;
    }

    @Override
    @Transactional(readOnly = true)
    public ComparisonResponse.ComparisonResultData getComparisonResult(String taskId) {
        logger.info("获取对比任务结果: taskId={}", taskId);

        try {
            ComparisonTask task = comparisonTaskRepository.findByTaskId(taskId);
            if (task == null) {
                throw new RuntimeException("对比任务不存在: " + taskId);
            }

            ComparisonResponse.ComparisonResultData result = new ComparisonResponse.ComparisonResultData();
            result.setTaskId(task.getTaskId());
            // 转换为中文状态
            result.setStatus(TaskStatusUtils.toChineseStatus(task.getStatus()));

            // 如果任务已完成，解析结果
            if ("completed".equals(task.getStatus()) && task.getResult() != null) {
                try {
                    List<ComparisonResponse.ResultMatrixItem> resultMatrix =
                        JSON.parseArray(task.getResult(), ComparisonResponse.ResultMatrixItem.class);
                    result.setResultMatrix(resultMatrix);
                } catch (Exception e) {
                    logger.warn("解析对比结果失败", e);
                    result.setResultMatrix(new ArrayList<>());
                }
            } else {
                result.setResultMatrix(new ArrayList<>());
            }

            return result;

        } catch (Exception e) {
            logger.error("获取对比任务结果失败", e);
            throw new RuntimeException("获取对比任务结果失败: " + e.getMessage());
        }
    }

    /**
     * 从文件信息推断供应商名称
     */
    private String extractSupplierNameFromFile(File file) {
        // 从文件路径中提取供应商名称
        String filePath = file.getFilePath();
        if (filePath != null) {
            // 简单的路径解析逻辑，这里可以根据实际的文件路径结构进行调整
            String[] parts = filePath.split("[\\\\/]");
            for (String part : parts) {
                // 优先匹配包含公司名称的路径段
                if (part.contains("公司") || part.contains("有限公司") || part.contains("股份有限公司")) {
                    // 清理路径中的多余信息，如"_虚拟标段_标包1_文件"
                    String cleanName = part.replaceAll("(_虚拟标段)?(_标包\\d+)?(_文件)?$", "");
                    return cleanName;
                }
            }
            // 如果没找到公司名称，尝试其他关键词
            for (String part : parts) {
                if (part.contains("供应商") || part.contains("投标") || part.length() > 10) {
                    return part.replaceAll("[_\\d]+$", ""); // 移除末尾的数字和下划线
                }
            }
        }
        return file.getSupplierId(); // 如果无法推断，返回供应商ID
    }

    /**
     * 转换文件信息
     */
    private ComparisonResponse.FileInfo convertToFileInfo(File file) {
        ComparisonResponse.FileInfo fileInfo = new ComparisonResponse.FileInfo();
        fileInfo.setFileId(file.getFileId());
        fileInfo.setFileName(file.getFileName());
        fileInfo.setFileType(getFileTypeName(file.getFileTypeId()));
        fileInfo.setFileSize(file.getFileSize());
        return fileInfo;
    }

    /**
     * 获取文件类型名称
     */
    private String getFileTypeName(Long fileTypeId) {
        // 这里可以根据实际的文件类型表进行查询
        // 简化处理，返回默认类型
        if (fileTypeId != null) {
            switch (fileTypeId.intValue()) {
                case 5: return "技术文件";
                case 6: return "商务文件";
                case 7: return "报价文件";
                default: return "其他文件";
            }
        }
        return "未知类型";
    }
}
