package com.gxwebsoft.ai.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.ai.constants.AuditContent3TripleConstants;
import com.gxwebsoft.ai.service.AuditContent3TripleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import cn.hutool.core.util.StrUtil;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AuditContent3TripleServiceImpl extends AbstractAuditContentService implements AuditContent3TripleService {

    // 工作流配置
    private static final String DIFY_WORKFLOW_TOKEN = "Bearer app-tjXbmHDE6daMbYOT4O13ev2X";
    
    // 三重一大分类定义 - 按照要求的顺序
    private static final List<String> CATEGORY_ORDER = Arrays.asList(
        AuditContent3TripleConstants.CATEGORY_MAJOR_DECISION,
        AuditContent3TripleConstants.CATEGORY_PERSONNEL_APPOINTMENT, 
        AuditContent3TripleConstants.CATEGORY_MAJOR_PROJECT,
        AuditContent3TripleConstants.CATEGORY_LARGE_FUND_OPERATION,
        AuditContent3TripleConstants.CATEGORY_DECISION_PROCEDURE
    );

    @Override
    public JSONObject generateTripleOneTableData(String kbIds, String libraryKbIds, String projectLibrary, String userName, String history, String suggestion) {
        log.info("开始生成三重一大制度对比分析表数据 - 用户: {}, kbIds: {}, libraryIds: {}, projectLibrary: {}", userName, kbIds, libraryKbIds, projectLibrary);
        
        long startTime = System.currentTimeMillis();
        
        try {
            // 异步并行处理每个分类
            Map<String, CompletableFuture<JSONArray>> futures = processCategoriesAsync(
                CATEGORY_ORDER, 
                category -> generateCategoryDataAsync(category, kbIds, libraryKbIds, projectLibrary, userName, history, suggestion)
            );
            
            // 等待所有异步任务完成
            CompletableFuture.allOf(futures.values().toArray(new CompletableFuture[0])).join();
            
            // 合并所有分类的结果
            JSONArray allData = mergeCategoryResults(CATEGORY_ORDER, futures);
            
            log.info("三重一大制度对比分析表生成成功 - 记录数: {}, 处理时间: {}ms", allData.size(), (System.currentTimeMillis() - startTime));
            
            return buildSuccessResponse(allData, startTime, "triple_one_audit");
            
        } catch (Exception e) {
            log.error("生成三重一大制度对比分析表失败", e);
            return buildErrorResponse("生成三重一大制度对比分析表失败: " + e.getMessage());
        }
    }

    /**
     * 异步生成单个分类的数据
     */
    @Async
    public CompletableFuture<JSONArray> generateCategoryDataAsync(String category, String kbIds, String libraryKbIds, String projectLibrary, String userName, String history, String suggestion) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                log.info("开始生成分类 {} 的数据", category);
                
                // 1. 为当前分类召回相关知识
                Map<String, List<String>> knowledgeSources = retrieveKnowledgeForCategory(
                    category, kbIds, libraryKbIds, projectLibrary
                );
                
                // 2. 构建完整的知识上下文（包含固定内容和动态内容）
                String knowledgeContext = buildCompleteKnowledgeContext(
                    category, knowledgeSources, history, suggestion
                );
                
                // 3. 调用工作流生成数据
                JSONObject requestBody = buildWorkflowRequest(knowledgeContext, userName);
                JSONArray categoryData = callWorkflow(DIFY_WORKFLOW_URL, DIFY_WORKFLOW_TOKEN, requestBody, "三重一大-" + category);
                
                log.info("分类 {} 数据生成完成，生成 {} 条记录", category, categoryData.size());
                return categoryData;
                
            } catch (Exception e) {
                log.error("生成分类 {} 数据失败", category, e);
                return new JSONArray();
            }
        });
    }

    /**
     * 为单个分类检索相关知识
     */
    private Map<String, List<String>> retrieveKnowledgeForCategory(String category, String kbIds, String libraryKbIds, String projectLibrary) {
        Map<String, List<String>> knowledgeSources = new HashMap<>();
        knowledgeSources.put("enterprise", new ArrayList<>());
        knowledgeSources.put("regulation", new ArrayList<>());
        knowledgeSources.put("auditCase", new ArrayList<>());
        
        // 构建当前分类的查询词
        List<String> categoryQueries = buildCategoryQueries(category);
        
        // 企业单位库检索
        if (StrUtil.isNotBlank(kbIds)) {
            Arrays.stream(kbIds.split(","))
                .map(String::trim)
                .filter(StrUtil::isNotBlank)
                .forEach(kbId -> knowledgeSources.get("enterprise")
                    .addAll(queryKnowledgeBase(kbId, categoryQueries, 100)));
        }
        
        // 公共法律法规库检索
        if (StrUtil.isNotBlank(libraryKbIds)) {
            Arrays.stream(libraryKbIds.split(","))
                .map(String::trim)
                .filter(StrUtil::isNotBlank)
                .forEach(libId -> knowledgeSources.get("regulation")
                    .addAll(queryKnowledgeBase(libId, categoryQueries, 80)));
        }
        
        // 审计案例库检索
        if (StrUtil.isNotBlank(projectLibrary)) {
            knowledgeSources.get("auditCase").addAll(
                queryKnowledgeBase(projectLibrary, categoryQueries, 60));
        }
        
        // 智能去重和排序
        knowledgeSources.forEach((key, list) -> {
            List<String> processed = list.stream()
                    .distinct()
                    .sorted(this::tripleOneComparator)
                    .limit(getLimitBySourceType(key))
                    .collect(Collectors.toList());
            knowledgeSources.put(key, processed);
        });
        
        log.debug("分类 {} 知识检索完成 - 企业: {}条, 法规: {}条, 案例: {}条", 
                 category, 
                 knowledgeSources.get("enterprise").size(),
                 knowledgeSources.get("regulation").size(),
                 knowledgeSources.get("auditCase").size());
        
        return knowledgeSources;
    }

    /**
     * 构建分类特定的查询词
     */
    private List<String> buildCategoryQueries(String category) {
        switch (category) {
            case AuditContent3TripleConstants.CATEGORY_MAJOR_DECISION:
                return Arrays.asList("重大决策事项 决策范围 决策程序", "重大决策制度 集体决策规定");
            case AuditContent3TripleConstants.CATEGORY_PERSONNEL_APPOINTMENT:
                return Arrays.asList("重要人事任免 人事任免范围", "中层管理人员 领导班子成员 任免");
            case AuditContent3TripleConstants.CATEGORY_MAJOR_PROJECT:
                return Arrays.asList("重大项目安排 项目安排范围", "年度投资计划 融资担保项目");
            case AuditContent3TripleConstants.CATEGORY_LARGE_FUND_OPERATION:
                return Arrays.asList("大额度资金运作 资金运作范围", "年度预算 大额度资金使用");
            case AuditContent3TripleConstants.CATEGORY_DECISION_PROCEDURE:
                return Arrays.asList("决策权力主体 决策程序", "集体决策 前置程序");
            default:
                return Arrays.asList(category + " 制度规定");
        }
    }

    /**
     * 构建完整的知识上下文 - 包含固定内容和动态内容
     */
    private String buildCompleteKnowledgeContext(String category, Map<String, List<String>> knowledgeSources, String history, String suggestion) {
        StringBuilder context = new StringBuilder();
        
        // 1. 三重一大制度对比分析要求
        context.append("## 三重一大制度对比分析要求 - ").append(category).append("\n");
        context.append("请基于以下知识生成").append(category).append("相关的三重一大制度对比分析表数据：\n\n");
        context.append("1. 仅关注与").append(category).append("直接相关的制度内容，过滤不相关制度\n");
        context.append("2. 对比分析政策内容、集团制度、公司制度的差异\n");
        context.append("3. 重点关注决策范围、金额标准、程序要求的差异\n");
        context.append("4. 识别制度执行中的风险和问题\n");
        context.append("5. 严格判断测试结果，只有证据充分才能判定为通过，证据不足或存在差异必须判定为不通过\n\n");
        
        // 2. 数据格式要求
        context.append("## 数据格式要求\n");
        context.append("需要生成").append(category).append("分类的数据，尽可能生成多个实例、多条记录：\n");
        context.append("- ").append(category).append("：").append(AuditContent3TripleConstants.CATEGORY_DESCRIPTIONS.get(category)).append("\n");
        context.append("\n");
        
        context.append("每条记录应包含6个字段：\n");
        context.append("- policyContent：国家法律法规和政策规定，需引用具体法规名称和条款\n");
        context.append("- groupSystem：集团层面的三重一大相关制度规定，非相关制度不得纳入\n");
        context.append("- companyFormulation：公司层面的三重一大相关制度规定及执行情况，需包含详细分析过程和查阅依据\n");
        context.append("- checkEvidence：审计检查的证据，需详细描述查阅过程、查阅的具体文件和内容\n");
        context.append("- testResult：审计测试的结果（通过/不通过），严格判断，从严掌握通过标准\n");
//        context.append("- workPaperIndex：相关《参考文件名FileId》，必须是实际存在的完整文件FileId，不能使用附表标题，确保能在文件夹中搜索到\n");
        context.append("- workPaperIndex：相关[\"实际存在的完整文件名||FileUrl\"]，必须是实际存在的完整文件名，不能使用附表标题，确保能在文件夹中搜索到\n");
        context.append("\n注意：\n");
        context.append("1. 请根据知识库内容尽可能全面地生成所有相关制度规定和检查点\n");
        context.append("2. 公司执行情况分析需包含：查阅了哪些文件、发现了什么内容、与制度的差异点、分析判断过程\n");
        context.append("3. 工作底稿索引必须准确对应实际文件名称，避免使用附表或章节标题\n");
        context.append("4. 测试结果判定需严格，对于制度不一致、执行不到位、证据不充分的情况必须判定为不通过\n");
        context.append("5. 审计检查的证据主要按公司制度为主，政策内容和集团制度为次要\n");
        context.append("6. 审计检查的证据增加判断公司制度是否与政策内容和集团制度相符\n");
        context.append("7. 历史问题整改分析：需核查历史问题是否已整改，结合最新时间材料（如最新会议纪要）分析当前是否存在相同问题\n");
        context.append("8. 项目上会核查：涉及三重一大的项目必须核查是否按规定上会，检查有无会议纪要作为证据\n");
        context.append("9. 制度权限关系：明确分析公司制度与集团制度的关联关系，权限设置必须遵循公司权限≤集团权限的原则\n");
        context.append("10. 层级关系识别：注意识别文件中的上级单位信息，分析制度执行是否符合层级管理要求\n\n");
        
        // 3. 参考数据（从常量类中获取）
        context.append("## 参考数据\n");
        context.append("### 政策内容\n").append(AuditContent3TripleConstants.POLICY_CONTENTS.get(category)).append("\n\n");
        context.append("### 集团制度\n").append(AuditContent3TripleConstants.GROUP_SYSTEMS.get(category)).append("\n\n");
        context.append("### 公司制度\n").append(AuditContent3TripleConstants.COMPANY_FORMULATIONS.get(category)).append("\n\n");
        
        // 4. 历史内容
        if (StrUtil.isNotBlank(history)) {
            context.append("## 历史生成内容\n");
            context.append("以下是之前生成的内容，请基于此进行优化：\n");
            context.append(history).append("\n\n");
        }
        
        // 5. 用户建议
        if (StrUtil.isNotBlank(suggestion)) {
            context.append("## 用户优化建议\n");
            context.append("请根据以下建议对生成内容进行调整：\n");
            context.append(suggestion).append("\n\n");
        }
        
        // 6. 企业单位知识
        if (!knowledgeSources.get("enterprise").isEmpty()) {
            context.append("## 企业单位知识\n");
            knowledgeSources.get("enterprise").forEach(knowledge -> 
                context.append(knowledge).append("\n"));
            context.append("\n");
        }
        
        // 7. 法律法规知识
        if (!knowledgeSources.get("regulation").isEmpty()) {
            context.append("## 法律法规知识\n");
            knowledgeSources.get("regulation").forEach(knowledge -> 
                context.append(knowledge).append("\n"));
            context.append("\n");
        }
        
        // 8. 审计案例知识
        if (!knowledgeSources.get("auditCase").isEmpty()) {
            context.append("## 审计案例知识\n");
            knowledgeSources.get("auditCase").forEach(knowledge -> 
                context.append(knowledge).append("\n"));
        }
        
        return context.toString();
    }

    /**
     * 三重一大相关性比较器
     */
    private int tripleOneComparator(String reg1, String reg2) {
        int score1 = calculateTripleOneRelevanceScore(reg1);
        int score2 = calculateTripleOneRelevanceScore(reg2);
        return Integer.compare(score2, score1);
    }

    /**
     * 计算三重一大相关性分数
     */
    private int calculateTripleOneRelevanceScore(String content) {
        return AuditContent3TripleConstants.KEYWORD_WEIGHTS.entrySet().stream()
                .filter(entry -> content.contains(entry.getKey()))
                .mapToInt(Map.Entry::getValue)
                .sum();
    }

    private int getLimitBySourceType(String sourceType) {
        switch (sourceType) {
            case "enterprise": return 100;
            case "regulation": return 80;
            case "auditCase": return 60;
            default: return 50;
        }
    }
}