// AuditContent4TargetServiceImpl.java
package com.gxwebsoft.ai.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.ai.constants.AuditContent4TargetConstants;
import com.gxwebsoft.ai.service.AuditContent4TargetService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import cn.hutool.core.util.StrUtil;

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

@Slf4j
@Service
public class AuditContent4TargetServiceImpl extends AbstractAuditContentService implements AuditContent4TargetService {

    // 工作流配置
    private static final String DIFY_WORKFLOW_TOKEN = "Bearer app-Z6YPjz3nAB46roFnZSfCTk3w";
    
    @Override
    public JSONObject generateTargetAuditTableData(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 {
            // 1. 检索相关知识
            Map<String, List<String>> knowledgeSources = retrieveKnowledgeForTargetResponsibility(
                kbIds, libraryKbIds, projectLibrary
            );
            
            // 2. 构建完整的知识上下文
            String knowledgeContext = buildCompleteKnowledgeContext(
                knowledgeSources, history, suggestion
            );
            
            // 3. 调用工作流生成数据
            JSONObject requestBody = buildWorkflowRequest(knowledgeContext, userName);
            JSONArray auditData = callWorkflow(DIFY_WORKFLOW_URL, DIFY_WORKFLOW_TOKEN, requestBody, "目标责任制审计");
            
            // 4. 后处理：确保数据格式正确
            auditData = processAuditData(auditData);
            
            log.info("目标责任制完成情况审计表生成成功 - 记录数: {}, 处理时间: {}ms", 
                    auditData.size(), (System.currentTimeMillis() - startTime));
            
            return buildSuccessResponse(auditData, startTime, "target_audit");
            
        } catch (Exception e) {
            log.error("生成目标责任制完成情况审计表失败", e);
            return buildErrorResponse("生成目标责任制完成情况审计表失败: " + e.getMessage());
        }
    }

    /**
     * 检索目标责任制相关知识
     */
    private Map<String, List<String>> retrieveKnowledgeForTargetResponsibility(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> queries = buildTargetResponsibilityQueries();
        
        // 企业单位库检索
        if (StrUtil.isNotBlank(kbIds)) {
            Arrays.stream(kbIds.split(","))
                .map(String::trim)
                .filter(StrUtil::isNotBlank)
                .forEach(kbId -> knowledgeSources.get("enterprise")
                    .addAll(queryKnowledgeBase(kbId, queries, 100)));
        }
        
        // 公共法律法规库检索
        if (StrUtil.isNotBlank(libraryKbIds)) {
            Arrays.stream(libraryKbIds.split(","))
                .map(String::trim)
                .filter(StrUtil::isNotBlank)
                .forEach(libId -> knowledgeSources.get("regulation")
                    .addAll(queryKnowledgeBase(libId, queries, 80)));
        }
        
        // 审计案例库检索
        if (StrUtil.isNotBlank(projectLibrary)) {
            knowledgeSources.get("auditCase").addAll(
                queryKnowledgeBase(projectLibrary, queries, 60));
        }
        
        // 智能去重和排序
        knowledgeSources.forEach((key, list) -> {
            List<String> processed = list.stream()
                    .distinct()
                    .sorted(this::targetResponsibilityComparator)
                    .limit(getLimitBySourceType(key))
                    .collect(Collectors.toList());
            knowledgeSources.put(key, processed);
        });
        
        log.debug("目标责任制知识检索完成 - 企业: {}条, 法规: {}条, 案例: {}条", 
                 knowledgeSources.get("enterprise").size(),
                 knowledgeSources.get("regulation").size(),
                 knowledgeSources.get("auditCase").size());
        
        return knowledgeSources;
    }
    
    /**
     * 构建目标责任制查询词
     */
    private List<String> buildTargetResponsibilityQueries() {
        return Arrays.asList(
            "目标责任 目标责任制 目标任务",
            "下达文件 计划文件 考核办法",
            "完成情况 未完成原因 考核结果",
            "上级主管 主管部门",
            "年度计划 工作目标 考核指标",
            "责任书 责任状 目标考核",
            "经营目标 工作计划 绩效考核",
            "重点工作 专项任务 年度总结"
        );
    }

    /**
     * 构建完整的知识上下文
     */
    private String buildCompleteKnowledgeContext(Map<String, List<String>> knowledgeSources, 
                                               String history, String suggestion) {
        StringBuilder context = new StringBuilder();
        
        // 1. 核心审计任务
        context.append("## 核心审计任务\n");
        context.append("审计分类：").append(AuditContent4TargetConstants.CATEGORY_TARGET_RESPONSIBILITY).append("\n");
        context.append("审计描述：检查被审计领导干部任职期间，对照上级主管部门下达的目标责任或单位自定的目标责任，检查其完成情况\n\n");
        
        // 2. 审计框架（审计规则）
        context.append("## 审计框架（审计规则）\n");
        context.append("以下审计框架定义了审计范围和要点，请基于此框架开展工作：\n");
        context.append(AuditContent4TargetConstants.AUDIT_FRAMEWORK).append("\n\n");
        
        // 3. 审计目标
        context.append("## 审计目标\n");
        context.append(AuditContent4TargetConstants.AUDIT_OBJECTIVE).append("\n\n");
        
        // 4. 审计工作原则
        context.append("## 审计工作原则\n");
        context.append(AuditContent4TargetConstants.AUDIT_PRINCIPLES).append("\n\n");
        
        // 5. 企业单位知识（主要考察内容）
        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");
        }
        
        // 6. 审计要点提示
        context.append("## 审计要点提示\n");
        context.append(AuditContent4TargetConstants.AUDIT_KEY_POINTS).append("\n\n");
        
        // 7. 数据格式要求
        context.append("## 数据格式要求\n");
        context.append("请生成JSON数组格式的审计表数据，每个审计条目包含以下字段：\n");
        context.append(AuditContent4TargetConstants.OUTPUT_FORMAT).append("\n\n");
        
        // 8. 审计证据要求
        context.append("## 审计证据要求\n");
        context.append(AuditContent4TargetConstants.AUDIT_EVIDENCE_REQUIREMENTS).append("\n\n");

        // 10. 法规和案例参考
        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");
        }
        
        // 11. 历史内容（如果有）
        if (StrUtil.isNotBlank(history)) {
            context.append("## 历史生成内容\n");
            context.append(history).append("\n\n");
        }
        
        // 12. 用户建议（如果有）
        if (StrUtil.isNotBlank(suggestion)) {
            context.append("## 用户建议\n");
            context.append(suggestion).append("\n\n");
        }

        // 9. 特别提醒（新增关键优化点）
        context.append("## 特别提醒\n");
        context.append("1. 审计证据必须包含具体的查阅过程：查阅了哪些文件、文件中发现了什么内容\n");
//        context.append("2. workPaperIndex必须填写实际存在的完整文件FileId，确保能在文件夹中搜索到\n");
        context.append("2. workPaperIndex必须填写实际存在的完整文件名||FileUrl，确保能在文件夹中搜索到\n");
        context.append("3. 完成情况判定必须基于充分证据：只有证据充分且完全符合要求才能判定为已完成\n");
        context.append("4. 对于执行不到位、效果不佳、证据不充分的情况必须在备注中说明\n");
        context.append("5. 尽可能识别知识库中所有相关年度，生成对应的审计记录\n");
//        context.append("6. 如果知识库中没有单位自定目标文件，请根据企业职责和上级目标合理推断单位自定计划内容\n");
        context.append("6. 不能填写简单的\"无\"，要提供有意义的描述\n");
        context.append("7. 对于正在进行的年度，完成情况应填写\"年度未结束无法评估\"\n");
        context.append("8. 如果知识库中有多个目标责任文件，每个文件都应生成独立的审计记录\n");
        context.append("9. 同一年度可能有不同类型的多个目标责任，应尽可能多地生成审计记录\n");
        context.append("10. 除了本次说明中提供的数据知识等依据，不能从其他地方读取数据，不能凭空捏造数据\n");
//        context.append("11. 不能填写简单的\"无\"，要提供有意义的描述\n");
//        context.append("12. 对于正在进行的年度，完成情况应填写\"无法评估\"\n\n");


        log.debug("目标责任制审计知识上下文长度: {} 字符", context.length());
        
        return context.toString();
    }

    /**
     * 目标责任制审计相关性比较器
     */
    private int targetResponsibilityComparator(String reg1, String reg2) {
        int score1 = calculateTargetResponsibilityRelevanceScore(reg1);
        int score2 = calculateTargetResponsibilityRelevanceScore(reg2);
        return Integer.compare(score2, score1); // 降序排序
    }

    /**
     * 计算目标责任制审计相关性分数
     */
    private int calculateTargetResponsibilityRelevanceScore(String content) {
        return AuditContent4TargetConstants.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 200; // 企业知识数量
            case "regulation": return 80;  // 法规数量
            case "auditCase": return 60;   // 案例数量
            default: return 50;
        }
    }
    
    /**
     * 后处理审计数据（优化字段处理逻辑）
     */
    private JSONArray processAuditData(JSONArray auditData) {
        if (auditData == null || auditData.isEmpty()) {
            return auditData;
        }
        
        JSONArray processedData = new JSONArray();
        
        for (int i = 0; i < auditData.size(); i++) {
            JSONObject item = auditData.getJSONObject(i);
            
            // 确保序号存在
            if (!item.containsKey("index") || item.getInteger("index") == null) {
                item.put("index", i + 1);
            }
            
            // 确保年度存在
            if (!item.containsKey("year") || StrUtil.isBlank(item.getString("year"))) {
                item.put("year", "未知年度");
            }
            
            // 优化单位自定计划字段：不能是简单的"无"
            String selfPlan = item.getString("selfPlan");
            if (StrUtil.isBlank(selfPlan) || "无".equals(selfPlan)) {
                String year = item.getString("year");
                item.put("selfPlan", year + "年度经营工作计划");
            }
            
            // 优化自定完成情况：不能是简单的"无"
            String selfCompletion = item.getString("selfCompletion");
            if (StrUtil.isBlank(selfCompletion) || "无".equals(selfCompletion)) {
                String superiorCompletion = item.getString("superiorCompletion");
                if ("已完成".equals(superiorCompletion)) {
                    item.put("selfCompletion", "已完成");
                } else if ("部分完成".equals(superiorCompletion)) {
                    item.put("selfCompletion", "部分完成");
                } else if ("未完成".equals(superiorCompletion)) {
                    item.put("selfCompletion", "未完成");
                } else if (superiorCompletion != null && 
                          (superiorCompletion.contains("尚未完成") || superiorCompletion.contains("年度未结束"))) {
                    item.put("selfCompletion", "年度未结束无法评估");
                } else {
                    item.put("selfCompletion", "未提供完成情况数据");
                }
            }
            
            // 优化自定未完成原因：不能是简单的"无"
            String selfReason = item.getString("selfReason");
            if (StrUtil.isBlank(selfReason) || "无".equals(selfReason)) {
                String selfComp = item.getString("selfCompletion");
                if ("已完成".equals(selfComp)) {
                    item.put("selfReason", "无未完成原因");
                } else if ("部分完成".equals(selfComp)) {
                    item.put("selfReason", "部分指标未达预期");
                } else if ("未完成".equals(selfComp)) {
                    item.put("selfReason", "经营目标未实现");
                } else if ("年度未结束无法评估".equals(selfComp)) {
                    item.put("selfReason", "年度尚未结束，无法评估");
                } else {
                    item.put("selfReason", "未提供原因分析");
                }
            }
            
            // 确保工作底稿索引是数组格式
//            if (!item.containsKey("workPaperIndex") || !(item.get("workPaperIndex") instanceof JSONArray)) {
//                JSONArray workPaperIndex = new JSONArray();
//                String year = item.getString("year");
//                workPaperIndex.add(year + "年度目标责任书");
//                workPaperIndex.add(year + "年度工作总结报告");
//                item.put("workPaperIndex", workPaperIndex);
//            }
            
            processedData.add(item);
        }
        
        return processedData;
    }
    
}