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";
    
    @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(
                AuditContent2StrategyConstants.CATEGORY_ORDER, 
                category -> generateCategoryDataAsync(category, kbIds, libraryKbIds, projectLibrary, userName, history, suggestion)
            );
            
            // 等待所有异步任务完成
            CompletableFuture.allOf(futures.values().toArray(new CompletableFuture[0])).join();
            
            // 合并所有分类的结果
            JSONArray allData = mergeCategoryResults(AuditContent2StrategyConstants.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 = AuditContent2StrategyConstants.CATEGORY_QUERIES.getOrDefault(
            category, Arrays.asList(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()
                    .limit(AuditContent2StrategyConstants.SOURCE_LIMITS.getOrDefault(key, 50))
                    .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 String buildCompleteKnowledgeContext(String category, Map<String, List<String>> knowledgeSources, 
                                               String history, String suggestion) {
        StringBuilder context = new StringBuilder();
        
        // 1. 核心审计任务
        context.append("## 核心审计任务\n");
        context.append(AuditContent2StrategyConstants.AUDIT_OBJECTIVE).append("\n\n");
        context.append("本次重点审计分类：").append(category).append("\n");
        context.append("对应发展理念：").append(AuditContent2StrategyConstants.CATEGORY_DEVELOPMENT_CONCEPT.get(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");
        context.append("**检查要求（满足以下任一条件即可）：**\n");
        context.append("1. **会议纪要路径**：检查是否有会议纪要证明按照\"党组织委员会→公司领导班子→董事会\"逐级开会落实；\n");
        context.append("   *或者*\n");
        context.append("2. **其他落实证据**：检查是否有其他材料（签批文件、任务分解、执行报告等）证明相关审计内容已从上往下逐级贯彻落实。\n");
        context.append("\n");
        context.append("**在检查证据中必须明确指出：**\n");
        context.append("①是否存在有效的贯彻落实证据（会议纪要或其他材料）；\n");
        context.append("②执行过程是否有充分材料支撑；\n");
        context.append("③执行结果是否达到预期。\n\n");
        
        // 3. 审计框架
        context.append("## 审计框架（审计规则）\n");
        String categoryFramework = AuditContent2StrategyConstants.CATEGORY_AUDIT_FRAMEWORK_FRAGMENTS.get(category);
        if (categoryFramework != null) {
            context.append(categoryFramework).append("\n");
        } else {
            context.append(AuditContent2StrategyConstants.AUDIT_FRAMEWORK).append("\n");
        }
        
        // 4. 企业单位知识（主要考察内容）
        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");
        } else {
            context.append("## 企业单位知识\n");
            context.append("未检索到相关企业资料，请基于审计框架生成审计内容。\n\n");
        }
        
        // 5. 审计工作原则
        context.append("## 审计工作原则\n");
        context.append(AuditContent2StrategyConstants.AUDIT_PRINCIPLES).append("\n\n");
        
        // 6. 数据格式要求
        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: 工作底稿索引（具体文件FileId）\n\n");
        context.append("4. workPaperIndex: 工作底稿索引（具体文件完整文件名||FileUrl）\n\n");
        
        // 7. 法规和案例参考（如果有）
        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");
        }
        
        // 8. 历史内容（如果有）
        if (StrUtil.isNotBlank(history)) {
            context.append("## 历史生成内容\n");
            context.append(history).append("\n\n");
        }
        
        // 9. 用户建议（如果有）
        if (StrUtil.isNotBlank(suggestion)) {
            context.append("## 用户建议\n");
            context.append(suggestion).append("\n");
        }
        
        // 记录上下文长度用于监控
        log.debug("分类 {} 构建的知识上下文长度: {} 字符", category, context.length());
        
        return context.toString();
    }
}