package com.gxwebsoft.ai.service.impl;

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

    // 工作流配置
    private static final String DIFY_WORKFLOW_TOKEN = "Bearer app-NpWFaPdBAl3LH7HqRXenlnVD";

    @Override
    public JSONObject generatePartyConductTableData(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 {
            // 获取所有子类（基于常量类中的映射关系）
            List<String> allSubCategories = AuditContent10PartyConductConstants.getAllSubCategories();
            log.info("共发现 {} 个子类需要处理", allSubCategories.size());
            
            // 异步并行处理每个子类
            Map<String, CompletableFuture<JSONArray>> futures = processCategoriesAsync(
                allSubCategories, 
                subCategory -> generateSubCategoryDataAsync(subCategory, kbIds, libraryKbIds, projectLibrary, userName, history, suggestion)
            );
            
            // 等待所有异步任务完成
            CompletableFuture.allOf(futures.values().toArray(new CompletableFuture[0])).join();
            
            // 合并所有子类的结果
            JSONArray allData = mergeCategoryResults(allSubCategories, futures);
            
            // 对结果进行排序（直接调用常量类的排序方法）
            AuditContent10PartyConductConstants.sortPartyConductData(allData);
            
            log.info("党风廉政建设责任制审计表生成成功 - 记录数: {}, 处理时间: {}ms", allData.size(), (System.currentTimeMillis() - startTime));
            
            return buildSuccessResponse(allData, startTime, "party_conduct_audit");
            
        } catch (Exception e) {
            log.error("生成党风廉政建设责任制审计表失败", e);
            return buildErrorResponse("生成党风廉政建设责任制审计表失败: " + e.getMessage());
        }
    }

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

    /**
     * 为单个子类检索相关知识
     */
    private Map<String, List<String>> retrieveKnowledgeForSubCategory(String subCategory, 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> subCategoryQueries = buildSubCategoryQueries(subCategory);
        
        // 企业单位库检索
        if (StrUtil.isNotBlank(kbIds)) {
            Arrays.stream(kbIds.split(","))
                .map(String::trim)
                .filter(StrUtil::isNotBlank)
                .forEach(kbId -> knowledgeSources.get("enterprise")
                    .addAll(queryKnowledgeBase(kbId, subCategoryQueries, 100)));
        }
        
        // 公共法律法规库检索
        if (StrUtil.isNotBlank(libraryKbIds)) {
            Arrays.stream(libraryKbIds.split(","))
                .map(String::trim)
                .filter(StrUtil::isNotBlank)
                .forEach(libId -> knowledgeSources.get("regulation")
                    .addAll(queryKnowledgeBase(libId, subCategoryQueries, 80)));
        }
        
        // 审计案例库检索
        if (StrUtil.isNotBlank(projectLibrary)) {
            knowledgeSources.get("auditCase").addAll(
                queryKnowledgeBase(projectLibrary, subCategoryQueries, 60));
        }
        
        // 智能去重和排序
        knowledgeSources.forEach((key, list) -> {
            List<String> processed = list.stream()
                    .distinct()
                    .sorted(this::partyConductComparator)
                    .limit(getLimitBySourceType(key))
                    .collect(Collectors.toList());
            knowledgeSources.put(key, processed);
        });
        
        log.debug("子类 {} 知识检索完成 - 企业: {}条, 法规: {}条, 案例: {}条", 
                 subCategory, 
                 knowledgeSources.get("enterprise").size(),
                 knowledgeSources.get("regulation").size(),
                 knowledgeSources.get("auditCase").size());
        
        return knowledgeSources;
    }

    /**
     * 构建子类特定的查询词
     */
    private List<String> buildSubCategoryQueries(String subCategory) {
        List<String> queries = new ArrayList<>();
        
        // 基础查询词
        queries.add(subCategory);
        queries.add(subCategory + " 制度规定");
        queries.add(subCategory + " 执行情况");
        
        // 根据子类类型添加特定查询词
        if (subCategory.equals(AuditContent10PartyConductConstants.SUBCATEGORY_MAIN_RESPONSIBILITY)) {
            queries.add("主体责任 监督责任 责任清单");
            queries.add("党风廉政建设责任制 党组责任 纪检责任");
        } else if (subCategory.equals(AuditContent10PartyConductConstants.SUBCATEGORY_EIGHT_REGULATIONS)) {
            queries.add("中央八项规定 监督检查 问题线索");
            queries.add("八项规定精神 违规问题 通报曝光");
        } else if (subCategory.equals(AuditContent10PartyConductConstants.SUBCATEGORY_ANTI_CORRUPTION)) {
            queries.add("群众身边腐败 四风问题 案件查处");
            queries.add("基层腐败 专项治理 长效机制");
        } else if (subCategory.equals(AuditContent10PartyConductConstants.SUBCATEGORY_DISCIPLINE_ENFORCEMENT)) {
            queries.add("政治纪律 组织纪律 政令畅通");
            queries.add("纪律执行 重大决策 转办督办");
        } else if (subCategory.equals(AuditContent10PartyConductConstants.SUBCATEGORY_MONTHLY_REPORT) || 
                   subCategory.equals(AuditContent10PartyConductConstants.SUBCATEGORY_RECTIFICATION_TASK) ||
                   subCategory.equals(AuditContent10PartyConductConstants.SUBCATEGORY_RECTIFICATION_ACCOUNTABILITY)) {
            queries.add("巡视整改 整改报告 整改措施");
            queries.add("巡视反馈 整改方案 整改完成");
        } else if (subCategory.equals(AuditContent10PartyConductConstants.SUBCATEGORY_THREE_TURNS) ||
                   subCategory.equals(AuditContent10PartyConductConstants.SUBCATEGORY_SYSTEM_CONSTRUCTION)) {
            queries.add("纪律检查体制改革 三转工作 纪检体制改革");
            queries.add("纪检制度建设 监督执纪问责");
        }
        
        return queries;
    }

    /**
     * 构建完整的知识上下文 - 包含完整的子类示例数据
     */
    private String buildCompleteKnowledgeContext(String subCategory, Map<String, List<String>> knowledgeSources, String history, String suggestion) {
        StringBuilder context = new StringBuilder();
        
        // 1. 获取当前子类的大类
        String category = findCategoryBySubCategory(subCategory);
        String categoryDesc = AuditContent10PartyConductConstants.CATEGORY_DESCRIPTIONS.getOrDefault(category, "");
        String subCategoryDesc = AuditContent10PartyConductConstants.SUBCATEGORY_DESCRIPTIONS.getOrDefault(subCategory, "");
        
        // 2. 党风廉政建设责任制审计要求
        context.append("## 党风廉政建设责任制审计要求\n");
        context.append("请基于以下知识生成").append(category).append("-").append(subCategory).append("相关的党风廉政建设责任制审计表数据：\n\n");
        context.append("1. 严格按照廉政情况表的结构生成数据：大类、子类、小类、内容、执行情况、工作底稿索引\n");
        context.append("2. **执行情况字段必须填写：详细情况内容说明，基于知识库证据判断，不能留空**\n");
        context.append("3. 工作底稿索引必须填写实际存在的完整文件名，确保能在文件夹中搜索到\n");
        context.append("4. 内容字段必须填写具体、可核查的检查点描述\n\n");
        
        // 3. 数据结构说明
        context.append("## 数据结构说明\n");
        context.append("当前大类：").append(category).append(" - ").append(categoryDesc).append("\n");
        context.append("当前子类：").append(subCategory).append(" - ").append(subCategoryDesc).append("\n");
        
        // 获取当前子类的小类列表
        List<String> detailCategories = AuditContent10PartyConductConstants.SUBCATEGORY_DETAIL_MAP.getOrDefault(subCategory, Collections.emptyList());
        if (!detailCategories.isEmpty()) {
            context.append("\n可用的子类包括：\n");
            for (String detailCategory : detailCategories) {
                context.append("- ").append(detailCategory).append("\n");
            }
        }
        
        context.append("\n可用的执行情况：详细情况内容说明\n\n");
        
        // 4. 完整的示例数据
        context.append("## 示例数据（参考结构）\n");
        String exampleDataJson = AuditContent10PartyConductConstants.getExampleDataJsonString(subCategory);
        context.append("以下是相关审计内容的").append(subCategory).append("的完整示例数据，请参考这些内容的结构生成：\n\n");
        context.append(exampleDataJson).append("\n\n");
        
        // 5. 历史内容
        if (StrUtil.isNotBlank(history)) {
            context.append("## 历史生成内容\n");
            context.append("以下是之前生成的内容，请基于此进行优化：\n");
            context.append(history).append("\n\n");
        }
        
        // 6. 用户建议
        if (StrUtil.isNotBlank(suggestion)) {
            context.append("## 用户优化建议\n");
            context.append("请根据以下建议对生成内容进行调整：\n");
            context.append(suggestion).append("\n\n");
        }
        
        // 7. 企业单位知识
        if (!knowledgeSources.get("enterprise").isEmpty()) {
            context.append("## 企业单位知识\n");
            knowledgeSources.get("enterprise").forEach(knowledge -> 
                context.append(knowledge).append("\n"));
            context.append("\n");
        }
        
        // 8. 法律法规知识
        if (!knowledgeSources.get("regulation").isEmpty()) {
            context.append("## 法律法规知识\n");
            knowledgeSources.get("regulation").forEach(knowledge -> 
                context.append(knowledge).append("\n"));
            context.append("\n");
        }
        
        // 9. 审计案例知识
        if (!knowledgeSources.get("auditCase").isEmpty()) {
            context.append("## 审计案例知识\n");
            knowledgeSources.get("auditCase").forEach(knowledge -> 
                context.append(knowledge).append("\n"));
            context.append("\n");
        }
        
        return context.toString();
    }
    
    /**
     * 根据子类查找对应的大类
     */
    private String findCategoryBySubCategory(String subCategory) {
        for (Map.Entry<String, List<String>> entry : AuditContent10PartyConductConstants.CATEGORY_SUBCATEGORY_MAP.entrySet()) {
            if (entry.getValue().contains(subCategory)) {
                return entry.getKey();
            }
        }
        return AuditContent10PartyConductConstants.CATEGORY_TARGET_RESPONSIBILITY; // 默认返回第一个大类
    }

    /**
     * 廉政情况相关性比较器
     */
    private int partyConductComparator(String reg1, String reg2) {
        int score1 = calculatePartyConductRelevanceScore(reg1);
        int score2 = calculatePartyConductRelevanceScore(reg2);
        return Integer.compare(score2, score1);
    }

    /**
     * 计算廉政情况相关性分数
     */
    private int calculatePartyConductRelevanceScore(String content) {
        return AuditContent10PartyConductConstants.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;
        }
    }
}