package com.gxwebsoft.ai.service.impl;

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

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

    @Override
    public JSONObject generateExpenseTableData(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 = retrieveKnowledgeForExpense(kbIds, libraryKbIds, projectLibrary);
            
            // 2. 构建完整的知识上下文
            String knowledgeContext = buildCompleteKnowledgeContext(knowledgeSources, history, suggestion);
            
            // 3. 调用工作流生成数据
            JSONObject requestBody = buildWorkflowRequest(knowledgeContext, userName);
            JSONArray expenseData = callWorkflow(DIFY_WORKFLOW_URL, DIFY_WORKFLOW_TOKEN, requestBody, "支出情况表");
            
            // 4. 数据验证和补充
            expenseData = validateAndEnhanceExpenseData(expenseData);
            
            log.info("支出情况表生成成功 - 记录数: {}, 处理时间: {}ms", 
                    expenseData.size(), (System.currentTimeMillis() - startTime));
            
            return buildSuccessResponse(expenseData, startTime, "expense_audit");
            
        } catch (Exception e) {
            log.error("生成支出情况表失败", e);
            return buildErrorResponse("生成支出情况表失败: " + e.getMessage());
        }
    }

    /**
     * 验证和增强支出情况表数据
     */
    private JSONArray validateAndEnhanceExpenseData(JSONArray originalData) {
        if (originalData == null || originalData.isEmpty()) {
            log.warn("原始数据为空，返回空数组");
            return new JSONArray();
        }
        
        JSONArray enhancedData = new JSONArray();
        
        for (int i = 0; i < originalData.size(); i++) {
            JSONObject item = originalData.getJSONObject(i);
            if (item != null) {
                // 确保所有必需字段都存在
                enhanceExpenseData(item);
                enhancedData.add(item);
            }
        }
        
        // 确保数据完整性（至少16条记录）
        if (enhancedData.size() < 16) {
            enhancedData = supplementMissingExpenseData(enhancedData);
        }
        
        log.info("数据增强完成 - 原始记录数: {}, 增强后记录数: {}", originalData.size(), enhancedData.size());
        return enhancedData;
    }

    /**
     * 增强单个支出数据
     */
    private void enhanceExpenseData(JSONObject expenseData) {
        // 确保支出类型正确
        String expenseType = expenseData.getString("expenseType");
        if (StrUtil.isBlank(expenseType) || !isValidExpenseType(expenseType)) {
            expenseData.put("expenseType", AuditContent1ExpenseConstants.EXPENSE_TYPE_RECEPTION);
        }
        
        // 确保年份在2020-2023范围内
        String year = expenseData.getString("year");
        if (StrUtil.isBlank(year) || !isValidYear(year)) {
            expenseData.put("year", "2023");
        }
        
        // 确保金额格式正确
        if (StrUtil.isBlank(expenseData.getString("finalStatementAmount"))) {
            expenseData.put("finalStatementAmount", "0.00");
        }
        
        if (StrUtil.isBlank(expenseData.getString("initialBudgetAmount"))) {
            expenseData.put("initialBudgetAmount", "0.00");
        }
        
        // 计算缺失的百分比字段
        calculateMissingPercentages(expenseData);
        
        // 确保数据来源
        if (StrUtil.isBlank(expenseData.getString("dataSource"))) {
            String yearStr = expenseData.getString("year");
            expenseData.put("dataSource", yearStr + "年度部门决算报表");
        }
        
        // 确保工作底稿索引是数组格式
        if (!expenseData.containsKey("workPaperIndex") || expenseData.get("workPaperIndex") == null) {
            JSONArray workPaperIndex = new JSONArray();
            workPaperIndex.add("《" + expenseData.getString("year") + "年度部门决算报表》");
            workPaperIndex.add("《" + expenseData.getString("year") + "年预算执行情况分析》");
            expenseData.put("workPaperIndex", workPaperIndex);
        }
    }

    /**
     * 补充缺失的支出数据
     */
    private JSONArray supplementMissingExpenseData(JSONArray existingData) {
        JSONArray supplementedData = new JSONArray();
        supplementedData.addAll(existingData);
        
        // 获取已存在的数据组合
        Set<String> existingCombinations = new HashSet<>();
        for (int i = 0; i < existingData.size(); i++) {
            JSONObject item = existingData.getJSONObject(i);
            String key = item.getString("expenseType") + "_" + item.getString("year");
            existingCombinations.add(key);
        }
        
        // 补充缺失的数据
        String[] expenseTypes = {
            AuditContent1ExpenseConstants.EXPENSE_TYPE_RECEPTION,
            AuditContent1ExpenseConstants.EXPENSE_TYPE_OVERSEAS,
            AuditContent1ExpenseConstants.EXPENSE_TYPE_VEHICLE,
            AuditContent1ExpenseConstants.EXPENSE_TYPE_MEETING
        };
        
        String[] years = {"2020", "2021", "2022", "2023"};
        
        for (String expenseType : expenseTypes) {
            for (String year : years) {
                String key = expenseType + "_" + year;
                if (!existingCombinations.contains(key)) {
                    JSONObject newItem = createDefaultExpenseRecord(expenseType, year);
                    supplementedData.add(newItem);
                }
            }
        }
        
        return supplementedData;
    }

    /**
     * 创建默认的支出记录
     */
    private JSONObject createDefaultExpenseRecord(String expenseType, String year) {
        JSONObject record = new JSONObject();
        record.put("expenseType", expenseType);
        record.put("year", year);
        record.put("finalStatementAmount", "0.00");
        record.put("initialBudgetAmount", "0.00");
        record.put("changePercentage", "0.0%");
        record.put("budgetRatio", "0.0%");
        record.put("remark", "根据年度财务报告数据生成");
        record.put("dataSource", year + "年度部门决算报表");
        
        JSONArray workPaperIndex = new JSONArray();
        workPaperIndex.add("《" + year + "年度部门决算报表》");
        workPaperIndex.add("《" + year + "年预算执行情况分析》");
        record.put("workPaperIndex", workPaperIndex);
        
        return record;
    }

    /**
     * 计算缺失的百分比字段
     */
    private void calculateMissingPercentages(JSONObject expenseData) {
        try {
            String finalAmountStr = expenseData.getString("finalStatementAmount").replace(",", "");
            String budgetAmountStr = expenseData.getString("initialBudgetAmount").replace(",", "");
            
            double finalAmount = Double.parseDouble(finalAmountStr);
            double budgetAmount = Double.parseDouble(budgetAmountStr);
            
            // 计算增减百分比
            if (budgetAmount > 0) {
                double changePercentage = ((finalAmount - budgetAmount) / budgetAmount) * 100;
                if (!expenseData.containsKey("changePercentage") || StrUtil.isBlank(expenseData.getString("changePercentage"))) {
                    expenseData.put("changePercentage", String.format("%.1f%%", changePercentage));
                }
                
                // 计算预算占比
                double budgetRatio = (finalAmount / budgetAmount) * 100;
                if (!expenseData.containsKey("budgetRatio") || StrUtil.isBlank(expenseData.getString("budgetRatio"))) {
                    expenseData.put("budgetRatio", String.format("%.1f%%", budgetRatio));
                }
            }
        } catch (Exception e) {
            log.warn("计算百分比失败: {}", e.getMessage());
        }
    }

    /**
     * 检查支出类型是否有效
     */
    private boolean isValidExpenseType(String expenseType) {
        return expenseType.equals(AuditContent1ExpenseConstants.EXPENSE_TYPE_RECEPTION) ||
               expenseType.equals(AuditContent1ExpenseConstants.EXPENSE_TYPE_OVERSEAS) ||
               expenseType.equals(AuditContent1ExpenseConstants.EXPENSE_TYPE_VEHICLE) ||
               expenseType.equals(AuditContent1ExpenseConstants.EXPENSE_TYPE_MEETING);
    }

    /**
     * 检查年份是否有效
     */
    private boolean isValidYear(String year) {
        for (int validYear : AuditContent1ExpenseConstants.YEAR_RANGE) {
            if (year.equals(String.valueOf(validYear))) {
                return true;
            }
        }
        return false;
    }

    /**
     * 检索支出情况表相关知识 - 优化查询策略
     */
    private Map<String, List<String>> retrieveKnowledgeForExpense(String kbIds, String libraryKbIds, String projectLibrary) {
        Map<String, List<String>> knowledgeSources = new HashMap<>();
        knowledgeSources.put("financial", new ArrayList<>());
        knowledgeSources.put("regulation", new ArrayList<>());
        knowledgeSources.put("auditCase", new ArrayList<>());
        
        // 构建更全面的查询词
        List<String> queries = buildEnhancedExpenseQueries();
        
        // 财务数据库检索
        if (StrUtil.isNotBlank(kbIds)) {
            Arrays.stream(kbIds.split(","))
                .map(String::trim)
                .filter(StrUtil::isNotBlank)
                .forEach(kbId -> {
                    List<String> financialKnowledge = queryKnowledgeBase(kbId, queries, 200);
                    knowledgeSources.get("financial").addAll(financialKnowledge);
                    log.debug("财务知识库 {} 检索到 {} 条相关知识", kbId, financialKnowledge.size());
                });
        }
        
        // 公共法律法规库检索
        if (StrUtil.isNotBlank(libraryKbIds)) {
            Arrays.stream(libraryKbIds.split(","))
                .map(String::trim)
                .filter(StrUtil::isNotBlank)
                .forEach(libId -> {
                    List<String> regulationKnowledge = queryKnowledgeBase(libId, queries, 100);
                    knowledgeSources.get("regulation").addAll(regulationKnowledge);
                });
        }
        
        // 审计案例库检索
        if (StrUtil.isNotBlank(projectLibrary)) {
            List<String> auditCaseKnowledge = queryKnowledgeBase(projectLibrary, queries, 50);
            knowledgeSources.get("auditCase").addAll(auditCaseKnowledge);
        }
        
        // 智能去重和排序
        knowledgeSources.forEach((key, list) -> {
            List<String> processed = list.stream()
                    .distinct()
                    .sorted(this::expenseComparator)
                    .limit(getLimitBySourceType(key))
                    .collect(Collectors.toList());
            knowledgeSources.put(key, processed);
        });
        
        log.info("支出情况表知识检索完成 - 财务: {}条, 法规: {}条, 案例: {}条", 
                 knowledgeSources.get("financial").size(),
                 knowledgeSources.get("regulation").size(),
                 knowledgeSources.get("auditCase").size());
        
        return knowledgeSources;
    }

    /**
     * 构建增强的支出情况表查询词
     */
    private List<String> buildEnhancedExpenseQueries() {
        return Arrays.asList(
            "决算报表 预算报表 财务报表 年度报告",
            "公务接待费 接待费用 招待费用 餐饮费用",
            "出国费用 出境费用 国际差旅 境外考察",
            "公车运行维护 车辆费用 汽车费用 交通费用",
            "会议费 培训费 会务费 培训费用",
            "八项规定 三公经费 公务支出",
            "预算执行 预算调整 超预算 预算控制",
            "2020年 2021年 2022年 2023年",
            "支出明细 费用明细 开支情况",
            "财务分析 费用分析 支出分析"
        );
    }

    /**
     * 构建完整的知识上下文 - 优化提示
     */
    private String buildCompleteKnowledgeContext(Map<String, List<String>> knowledgeSources, String history, String suggestion) {
        StringBuilder context = new StringBuilder();
        
        // 1. 支出情况表分析要求 - 增强要求
        context.append("## 支出情况表分析要求\n");
        context.append("请基于以下知识生成完整详细的公务接待/出国/公车运行维护/会议培训费等支出情况表数据：\n\n");
        context.append("1. 必须生成完整的支出情况表数据，覆盖2020-2023四个年度\n");
        context.append("2. 重点关注四类支出：公务接待、出国（出境）、公车运行维护、会议培训费\n");
        context.append("3. 从财务知识库中提取所有实际的支出数据，要求全面完整\n");
        context.append("4. 确保信息的准确性和完整性，包括决算数、预算数、增减情况和占比情况\n");
        context.append("5. 工作底稿索引必须准确对应实际文件名称，可以包含多个相关文件\n");
        context.append("6. 要求生成尽可能多、尽可能完整的支出记录，覆盖所有年份和支出类型\n\n");
        
        // 2. 数据格式要求
        context.append("## 数据格式要求\n");
        context.append("需要生成完整详细的支出情况表数据：\n\n");
        context.append(AuditContent1ExpenseConstants.DATA_FORMAT_REQUIREMENT);
        context.append("\n\n重要要求：\n");
        context.append("1. 必须根据知识库内容生成尽可能多、尽可能完整的支出信息\n");
        context.append("2. 工作底稿索引必须准确对应实际文件名称，避免使用附表或章节标题\n");
        context.append("3. 金额单位为元，保持两位小数，可以使用逗号分隔千位\n");
        context.append("4. 百分比计算要准确，增减情况正数表示增长，负数表示减少\n");
        context.append("5. 数据来源要具体，如：2023年度部门决算报表\n");
        context.append("6. 备注信息可以包含超支原因、特殊情况说明等\n\n");
        
        // 3. 历史内容
        if (StrUtil.isNotBlank(history)) {
            context.append("## 历史生成内容\n");
            context.append("以下是之前生成的内容，请基于此进行优化和补充：\n");
            context.append(history).append("\n\n");
        }
        
        // 4. 用户建议
        if (StrUtil.isNotBlank(suggestion)) {
            context.append("## 用户优化建议\n");
            context.append("请根据以下建议对生成内容进行调整：\n");
            context.append(suggestion).append("\n\n");
        }
        
        // 5. 财务知识
        if (!knowledgeSources.get("financial").isEmpty()) {
            context.append("## 财务知识\n");
            context.append("这是财务相关的报表和文件信息，请仔细分析并提取所有支出数据：\n");
            knowledgeSources.get("financial").forEach(knowledge -> 
                context.append(knowledge).append("\n"));
            context.append("\n");
        }
        
        // 6. 法律法规知识
        if (!knowledgeSources.get("regulation").isEmpty()) {
            context.append("## 法律法规知识\n");
            knowledgeSources.get("regulation").forEach(knowledge -> 
                context.append(knowledge).append("\n"));
            context.append("\n");
        }
        
        // 7. 审计案例知识
        if (!knowledgeSources.get("auditCase").isEmpty()) {
            context.append("## 审计案例知识\n");
            knowledgeSources.get("auditCase").forEach(knowledge -> 
                context.append(knowledge).append("\n"));
        }
        
        log.debug("构建的知识上下文长度: {}", context.length());
        return context.toString();
    }

    /**
     * 支出情况表相关性比较器
     */
    private int expenseComparator(String content1, String content2) {
        int score1 = calculateExpenseRelevanceScore(content1);
        int score2 = calculateExpenseRelevanceScore(content2);
        return Integer.compare(score2, score1);
    }

    /**
     * 计算支出情况表相关性分数
     */
    private int calculateExpenseRelevanceScore(String content) {
        return AuditContent1ExpenseConstants.KEYWORD_WEIGHTS.entrySet().stream()
                .filter(entry -> content.contains(entry.getKey()))
                .mapToInt(Map.Entry::getValue)
                .sum();
    }

    private int getLimitBySourceType(String sourceType) {
        switch (sourceType) {
            case "financial": return 150;
            case "regulation": return 80;
            case "auditCase": return 40;
            default: return 100;
        }
    }
}