package com.gxwebsoft.ai.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.ai.dto.AuditEvidenceRequest;
import com.gxwebsoft.ai.service.AuditEvidenceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;

import java.util.Date;

@Slf4j
@Service
public class AuditEvidenceServiceImpl implements AuditEvidenceService {

    // Dify工作流配置
    private static final String DIFY_WORKFLOW_URL = "http://1.14.159.185:8180/v1/workflows/run";
    private static final String DIFY_WORKFLOW_TOKEN = "Bearer app-DEhvF537rQfy6MvH9KeBKUVj";

    @Override
    public JSONObject generateAuditEvidence(AuditEvidenceRequest request) {
        log.info("开始生成审计取证单 - 用户: {}, 项目: {}", request.getUserName(), request.getProjectName());
        
        long startTime = System.currentTimeMillis();
        
        try {
            // 1. 构建完整上下文
            String knowledgeContext = buildCompleteContext(request);
            
            // 2. 构建工作流请求
            JSONObject requestBody = buildWorkflowRequest(knowledgeContext, request.getUserName());
            
            // 3. 调用Dify工作流
            JSONObject result = callWorkflow(requestBody, "审计取证单");
            
            // 4. 添加处理时间等信息
            result.put("success", true);
            result.put("processing_time", (System.currentTimeMillis() - startTime) + "ms");
            result.put("generated_time", new Date().toString());
            
            log.info("审计取证单生成成功 - 处理时间: {}ms", (System.currentTimeMillis() - startTime));
            
            return result;
            
        } catch (Exception e) {
            log.error("生成审计取证单失败", e);
            return buildErrorResponse("生成审计取证单失败: " + e.getMessage());
        }
    }

    /**
     * 构建完整上下文
     */
    private String buildCompleteContext(AuditEvidenceRequest request) {
        StringBuilder context = new StringBuilder();
        
        // 1. 审计取证单生成要求
        context.append("## 审计取证单生成要求\n");
        context.append("请基于以下信息生成一份完整的审计取证单。审计取证单是审计工作中的重要文书，用于记录审计发现的问题、事实依据、处理建议等。\n\n");
        
        // 2. 输出格式要求
        context.append("## 输出格式要求\n");
        context.append("请严格按照以下JSON格式输出，不要包含任何额外文本：\n");
        context.append("{\n");
//        context.append("  \"caseIndex\": \"案件编号，如审计-[2024]-001\",\n");
//        context.append("  \"projectName\": \"具体项目名称\",\n");
        context.append("  \"auditedTarget\": \"被审计单位或个人\",\n");
        context.append("  \"auditMatter\": \"审计事项描述\",\n");
        context.append("  \"summaryTitle\": \"核心问题标题\",\n");
        context.append("  \"auditRecord\": \"客观的审计核查事实记录，包括时间、地点、主体、行为、数据等\",\n");
        context.append("  \"auditFinding\": \"审计发现的具体问题、性质及影响\",\n");
        context.append("  \"evidenceBasis\": \"定性依据，引用法规、制度或合同条款\",\n");
        context.append("  \"handling\": \"拟采取的处理措施\",\n");
        context.append("  \"suggestion\": \"改进或整改建议\",\n");
        context.append("  \"attachment\": \"列示随附的证明材料（只出现材料中文名称，不要出现FileId，不要出现网站链接）\",\n");
        context.append("  \"auditors\": \"审计人员姓名\",\n");
        context.append("  \"compileDate\": \"编制日期，格式：YYYY-MM-DD\",\n");
        context.append("  \"providerOpinion\": \"证据提供单位或个人意见\",\n");
        context.append("  \"providerDate\": \"证据提供日期，格式：YYYY-MM-DD\",\n");
        context.append("  \"attachmentPages\": \"附件页数，如：2\",\n");
        context.append("  \"feedbackDeadline\": \"反馈期限，如：5个工作日内\"\n");
        context.append("}\n");
        
        // 3. 字段内容要求
        context.append("## 字段内容具体要求\n");
        context.append("1. **审计记录**：客观记录审计核查的具体事实，包括时间、地点、主体、行为、数据等，避免主观评价。\n");
        context.append("2. **审计发现**：基于审计记录提出具体问题性质，先事实后定性，避免夸大。\n");
        context.append("3. **定性依据**：必须引用具体的法规、制度或合同条款，格式如：根据《XX法》第XX条规定...\n");
        context.append("4. **处理措施**：针对发现的问题提出具体的处理措施，要有可操作性。\n");
        context.append("5. **建议**：针对问题根源提出改进或整改建议，要具体可行。\n");
        context.append("6. **日期**：所有日期必须使用YYYY-MM-DD格式。\n\n");
        
        // 4. 用户提供的基础信息
        if (StrUtil.isNotBlank(request.getProjectName()) || 
            StrUtil.isNotBlank(request.getAuditedTarget()) ||
            StrUtil.isNotBlank(request.getAuditMatter())) {
            
            context.append("## 用户提供的基础信息\n");
            
            if (StrUtil.isNotBlank(request.getProjectName())) {
                context.append("- 项目名称：").append(request.getProjectName()).append("\n");
            }
            if (StrUtil.isNotBlank(request.getAuditedTarget())) {
                context.append("- 被审计单位/个人：").append(request.getAuditedTarget()).append("\n");
            }
            if (StrUtil.isNotBlank(request.getAuditMatter())) {
                context.append("- 审计事项：").append(request.getAuditMatter()).append("\n");
            }
            if (StrUtil.isNotBlank(request.getSummaryTitle())) {
                context.append("- 标题：").append(request.getSummaryTitle()).append("\n");
            }
            context.append("\n");
        }
        
        // 5. 历史内容（如果存在）
        if (StrUtil.isNotBlank(request.getHistory())) {
            context.append("## 历史内容参考\n");
            context.append("以下是与本次审计相关的历史内容，请参考但不完全照搬：\n");
            context.append(request.getHistory()).append("\n\n");
        }
        
        // 6. 额外要求
        context.append("## 额外要求\n");
        context.append("1. 内容必须真实、准确、完整，符合审计文书规范\n");
        context.append("2. 语言表述要严谨、客观、规范\n");
        context.append("3. 各字段内容要相互衔接，逻辑清晰\n");
        context.append("4. 如果某些信息不明确，请根据审计常规进行合理补充\n");
        
        log.debug("构建的上下文长度: {}", context.length());
        return context.toString();
    }

    /**
     * 构建工作流请求
     */
    private JSONObject buildWorkflowRequest(String knowledge, String userName) {
        JSONObject requestBody = new JSONObject();
        JSONObject inputs = new JSONObject();
        
        inputs.put("knowledge", knowledge);
        
        requestBody.put("inputs", inputs);
        requestBody.put("response_mode", "blocking");
        requestBody.put("user", userName);
        requestBody.put("timeout", 300); // 5分钟超时
        
        return requestBody;
    }

    /**
     * 调用工作流
     */
    private JSONObject callWorkflow(JSONObject requestBody, String workflowName) {
        try {
            log.info("调用{}工作流，请求体长度: {}", workflowName, requestBody.toString().length());
            
            String result = HttpUtil.createPost(DIFY_WORKFLOW_URL)
                    .header("Authorization", DIFY_WORKFLOW_TOKEN)
                    .header("Content-Type", "application/json")
                    .body(requestBody.toString())
                    .timeout(5 * 60 * 1000) // 5分钟
                    .execute()
                    .body();
            
            log.info("{}工作流返回结果长度: {}", workflowName, result.length());
            
            JSONObject jsonResponse = JSONObject.parseObject(result);
            
            // 提取输出文本
            String outputText = jsonResponse.getJSONObject("data")
                                          .getJSONObject("outputs")
                                          .getString("result");
            
            if (StrUtil.isBlank(outputText)) {
                log.warn("{}工作流返回结果为空", workflowName);
                return new JSONObject();
            }
            
            // 解析为JSON对象
            JSONObject auditEvidence = JSONObject.parseObject(outputText);
            
            log.info("成功解析{}工作流返回数据", workflowName);
            return auditEvidence;
            
        } catch (Exception e) {
            log.error("调用{}工作流失败", workflowName, e);
            throw new RuntimeException("调用" + workflowName + "工作流失败: " + e.getMessage(), e);
        }
    }

    /**
     * 构建错误响应
     */
    private JSONObject buildErrorResponse(String errorMessage) {
        JSONObject result = new JSONObject();
        result.put("success", false);
        result.put("error", errorMessage);
        result.put("timestamp", System.currentTimeMillis());
        return result;
    }
}