package com.gxwebsoft.ai.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.ai.constants.AuditContent2StrategyConstants;
import com.gxwebsoft.ai.service.AuditContent2StrategyService;
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 AuditContent2StrategyServiceImpl extends AbstractAuditContentService implements AuditContent2StrategyService {

    // 工作流配置
    private static final String DIFY_WORKFLOW_TOKEN = "Bearer app-3cPaXHIPFPS6lIfMGV67NOu0";
    
    // 分类定义 - 调整为5个分类
    private static final List<String> CATEGORY_ORDER = Arrays.asList(
        AuditContent2StrategyConstants.CATEGORY_GOVERNANCE_REFORM,
        AuditContent2StrategyConstants.CATEGORY_DEVELOPMENT_STRATEGY,
        AuditContent2StrategyConstants.CATEGORY_RISK_PREVENTION,
        AuditContent2StrategyConstants.CATEGORY_SOCIAL_ENVIRONMENTAL,
        AuditContent2StrategyConstants.CATEGORY_PERFORMANCE_ASSESSMENT
    );

    @Override
    public JSONObject generateStrategyAuditTableData(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, "strategy_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, 150))); // 增加检索数量
        }
        
        // 公共法律法规库检索
        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::strategyAuditComparator)
                    .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 AuditContent2StrategyConstants.CATEGORY_GOVERNANCE_REFORM:
                return Arrays.asList("法人治理 薪酬改革 国有资产管理", "改革创新 治理结构 董事会");
            case AuditContent2StrategyConstants.CATEGORY_DEVELOPMENT_STRATEGY:
                return Arrays.asList("混合所有制 剥离办社会职能 改革措施", "协调发展 改革方案 政策落实");
            case AuditContent2StrategyConstants.CATEGORY_RISK_PREVENTION:
                return Arrays.asList("发展规划 金融风险 债务风险", "绿色发展 风险防控 资产负债率");
            case AuditContent2StrategyConstants.CATEGORY_SOCIAL_ENVIRONMENTAL:
                return Arrays.asList("精准扶贫 污染防治 环境保护", "开放共享 社会责任 定点扶贫");
            case AuditContent2StrategyConstants.CATEGORY_PERFORMANCE_ASSESSMENT:
                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("## 核心审计任务\n");
        context.append("为以下审计分类生成具体的审计表内容：\n");
        context.append("分类：").append(category).append("\n");
        context.append("描述：").append(AuditContent2StrategyConstants.CATEGORY_DESCRIPTIONS.get(category)).append("\n");
        context.append("审计重点：").append(AuditContent2StrategyConstants.getBriefAuditFrameworkForCategory(category)).append("\n\n");
        
        // 2. 审计框架（只传入当前分类相关的部分）
        context.append("## 审计框架（审计规则）\n");
        context.append("以下审计框架定义了审计范围和要点，请基于此框架开展工作：\n");
        
        // 获取当前分类相关的审计框架片段
        String categoryFramework = AuditContent2StrategyConstants.CATEGORY_AUDIT_FRAMEWORK_FRAGMENTS.get(category);
        if (categoryFramework != null) {
            context.append(categoryFramework).append("\n");
        } else {
            // 如果找不到对应分类，则使用完整的框架（保底）
            log.warn("未找到分类 {} 对应的审计框架片段，使用完整框架", category);
            context.append(AuditContent2StrategyConstants.AUDIT_FRAMEWORK).append("\n");
        }
        
        // 3. 企业单位知识（主要考察内容）
        if (!knowledgeSources.get("enterprise").isEmpty()) {
            context.append("## 企业单位知识（具体考察内容）\n");
            context.append("以下是企业单位的实际资料，请基于审计框架，结合这些具体内容生成审计记录：\n\n");
            knowledgeSources.get("enterprise").forEach(knowledge -> 
                context.append("• ").append(knowledge).append("\n"));
            context.append("\n");
        }
        
        // 4. 审计工作原则
        context.append("## 审计工作原则\n");
        context.append(AuditContent2StrategyConstants.AUDIT_PRINCIPLES).append("\n\n");
        
        // 5. 数据格式要求（精简版）
        context.append("## 数据格式要求\n");
        context.append("生成JSON数组，每个元素包含4个字段：\n");
        context.append("1. auditContent: 具体审计内容（基于框架，结合企业实际）\n");
        context.append("2. checkEvidence: 检查证据（引用企业具体文件）\n");
        context.append("3. testResult: 测试结果（通过/不通过）（基于充分证据严格判断）\n");
        context.append("4. workPaperIndex: 工作底稿索引（具体文件名）\n\n");
        
        // 6. 法规和案例参考
        if (!knowledgeSources.get("regulation").isEmpty()) {
            context.append("## 法律法规参考\n");
            knowledgeSources.get("regulation").forEach(knowledge -> 
                context.append("• ").append(knowledge).append("\n"));
            context.append("\n");
        }
        
        if (!knowledgeSources.get("auditCase").isEmpty()) {
            context.append("## 审计案例参考\n");
            knowledgeSources.get("auditCase").forEach(knowledge -> 
                context.append("• ").append(knowledge).append("\n"));
            context.append("\n");
        }
        
        // 7. 历史内容（如果有）
        if (StrUtil.isNotBlank(history)) {
            context.append("## 历史生成内容\n");
            context.append(history).append("\n\n");
        }
        
        // 8. 用户建议（如果有）
        if (StrUtil.isNotBlank(suggestion)) {
            context.append("## 用户建议\n");
            context.append(suggestion).append("\n");
        }
        
        // 记录上下文长度用于监控
        log.debug("分类 {} 构建的知识上下文长度: {} 字符", category, context.length());
        
        return context.toString();
    }

    /**
     * 发展战略审计相关性比较器
     */
    private int strategyAuditComparator(String reg1, String reg2) {
        int score1 = calculateStrategyAuditRelevanceScore(reg1);
        int score2 = calculateStrategyAuditRelevanceScore(reg2);
        return Integer.compare(score2, score1);
    }

    /**
     * 计算发展战略审计相关性分数
     */
    private int calculateStrategyAuditRelevanceScore(String content) {
        return AuditContent2StrategyConstants.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 120; // 增加企业知识数量
            case "regulation": return 60;  // 减少法规数量
            case "auditCase": return 40;   // 减少案例数量
            default: return 50;
        }
    }
    
    /**
     * 获取当前分类相关的审计框架内容
     * 这是一个辅助方法，方便其他地方调用
     */
    private String getAuditFrameworkForCategory(String category) {
        String framework = AuditContent2StrategyConstants.CATEGORY_AUDIT_FRAMEWORK_FRAGMENTS.get(category);
        return framework != null ? framework : AuditContent2StrategyConstants.AUDIT_FRAMEWORK;
    }
}