package com.gxwebsoft.ai.service.impl;

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

    // 工作流配置
    private static final String DIFY_WORKFLOW_TOKEN = "Bearer app-lsqVD2hTWYQpA89SDSr9s3dH";
    
    @Override
    public JSONObject generateStateAssetsAuditTableData(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 = retrieveKnowledgeForStateAssetsManagement(
                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, "state_assets_audit");
            
        } catch (Exception e) {
            log.error("生成国有资产管理审计表失败", e);
            return buildErrorResponse("生成国有资产管理审计表失败: " + e.getMessage());
        }
    }

    /**
     * 检索国资管理相关知识
     */
    private Map<String, List<String>> retrieveKnowledgeForStateAssetsManagement(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 = buildStateAssetsQueries();
        
        // 企业单位库检索 - 增加查询深度
        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, 100)));
        }
        
        // 审计案例库检索
        if (StrUtil.isNotBlank(projectLibrary)) {
            knowledgeSources.get("auditCase").addAll(
                queryKnowledgeBase(projectLibrary, queries, 80));
        }
        
        // 智能去重和排序
        knowledgeSources.forEach((key, list) -> {
            List<String> processed = list.stream()
                    .map(String::trim)  // 去除首尾空格
                    .filter(str -> !StrUtil.isBlank(str))  // 过滤空字符串
                    .distinct()
                    .sorted(this::stateAssetsManagementComparator)
                    .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> buildStateAssetsQueries() {
        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(AuditContent6StateAssetsConstants.CATEGORY_STATE_ASSETS_MANAGEMENT).append("\n");
        context.append("审计描述：检查国有资产管理情况和政府采购执行情况，确保资产安全完整和采购规范\n\n");
        
        // 2. 审计框架（审计规则）
        context.append("## 审计框架（审计规则）\n");
        context.append("以下审计框架定义了审计范围和要点，请基于此框架开展工作：\n");
        context.append(AuditContent6StateAssetsConstants.AUDIT_FRAMEWORK).append("\n\n");
        
        // 3. 审计目标
        context.append("## 审计目标\n");
        context.append(AuditContent6StateAssetsConstants.AUDIT_OBJECTIVE).append("\n\n");
        
        // 4. 审计工作原则
        context.append("## 审计工作原则\n");
        context.append(AuditContent6StateAssetsConstants.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(AuditContent6StateAssetsConstants.AUDIT_KEY_POINTS).append("\n\n");
        
        // 7. 数据格式要求
        context.append("## 数据格式要求\n");
        context.append("请生成JSON数组格式的审计表数据，每个审计条目包含以下字段：\n");
        context.append(AuditContent6StateAssetsConstants.OUTPUT_FORMAT).append("\n\n");
        
        // 8. 审计证据要求
        context.append("## 审计证据要求\n");
        context.append(AuditContent6StateAssetsConstants.AUDIT_EVIDENCE_REQUIREMENTS).append("\n\n");
        
        // 9. 特别提醒 - 强调全面识别
        context.append("## 特别提醒\n");
        context.append("1. 必须全面识别知识库中所有国有资产，包括：房屋、土地、车辆、机械设备、办公设备、电子设备、家具、无形资产等\n");
        context.append("2. 每个独立的资产都要生成独立的审计记录，不限制数量，尽可能多地生成\n");
        context.append("3. 即使资产信息不完整，也要基于现有信息生成审计记录\n");
//        context.append("4. workPaperIndex必须填写实际存在的完整文件FileId\n");
        context.append("4. workPaperIndex必须填写实际存在的完整文件名||FileUrl\n");
        context.append("5. 对于未出租资产，承租方、合同金额等字段填写\"未出租\"\n");
        context.append("6. 备注中应详细说明资产状况、使用情况、合规性评价\n");
        context.append("7. 不能填写简单的\"无\"，要提供有意义的描述\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");
        }
        
        log.debug("国资管理审计知识上下文长度: {} 字符", context.length());
        
        return context.toString();
    }

    /**
     * 国资管理审计相关性比较器
     */
    private int stateAssetsManagementComparator(String reg1, String reg2) {
        int score1 = calculateStateAssetsRelevanceScore(reg1);
        int score2 = calculateStateAssetsRelevanceScore(reg2);
        return Integer.compare(score2, score1); // 降序排序
    }

    /**
     * 计算国资管理审计相关性分数
     */
    private int calculateStateAssetsRelevanceScore(String content) {
        return AuditContent6StateAssetsConstants.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 300; // 增加企业知识数量
            case "regulation": return 60;
            case "auditCase": return 40;
            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("assetName") || StrUtil.isBlank(item.getString("assetName"))) {
                item.put("assetName", "国有资产" + (i + 1));
            }
            
            // 优化取得方式
            String acquisitionMethod = item.getString("acquisitionMethod");
            if (StrUtil.isBlank(acquisitionMethod) || "无".equals(acquisitionMethod)) {
                item.put("acquisitionMethod", "购置");
            }
            
            // 优化资产价值
            String assetValue = item.getString("assetValue");
            if (StrUtil.isBlank(assetValue) || "无".equals(assetValue)) {
                item.put("assetValue", "待评估");
            }
            
            // 优化面积
            String area = item.getString("area");
            if (StrUtil.isBlank(area) || "无".equals(area)) {
                item.put("area", "未提供");
            }
            
            // 优化出租相关字段
            String platformLease = item.getString("platformLease");
            if (StrUtil.isBlank(platformLease) || "无".equals(platformLease)) {
                item.put("platformLease", "否");
            }
            
            String tenant = item.getString("tenant");
            if (StrUtil.isBlank(tenant) || "无".equals(tenant) || tenant.contains("无")) {
                item.put("tenant", "未出租");
                item.put("contractAmount", "未出租");
                item.put("leasePeriod", "未出租");
                item.put("rentPaymentTime", "未出租");
                item.put("approvalDoc", "未出租");
            }
            
            // 优化是否纳入预算
            String inBudget = item.getString("inBudget");
            if (StrUtil.isBlank(inBudget) || "无".equals(inBudget)) {
                item.put("inBudget", "是");
            }
            
            // 确保工作底稿索引是数组格式
//            if (!item.containsKey("workPaperIndex") || !(item.get("workPaperIndex") instanceof JSONArray)) {
//                JSONArray workPaperIndex = new JSONArray();
//                String assetName = item.getString("assetName");
//                workPaperIndex.add(assetName + "资产登记台账");
//                item.put("workPaperIndex", workPaperIndex);
//            }
            
            processedData.add(item);
        }
        
        return processedData;
    }
    
}