package com.gxwebsoft.ai.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.ai.dto.AuditEvidenceRequest;
import com.gxwebsoft.ai.entity.AuditEvidence;
import com.gxwebsoft.ai.enums.AuditMatterTypeEnum;
import com.gxwebsoft.ai.mapper.AuditEvidenceMapper;
import com.gxwebsoft.ai.param.AuditEvidenceParam;
import com.gxwebsoft.ai.service.AuditEvidenceService;
import com.gxwebsoft.common.core.Constants;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

@Slf4j
@Service
public class AuditEvidenceServiceImpl extends ServiceImpl<AuditEvidenceMapper, AuditEvidence> 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 ApiResult<AuditEvidence> 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 工作流
            AuditEvidence result = callWorkflow(requestBody);
            
            // 4. 保存到数据库
//            saveToDatabase(result, request);
            
            // 5. 添加处理时间等信息
            if (result != null) {
                result.setSuccess(true);
                log.info("审计取证单生成成功 - ID: {}, 处理时间：{}ms", result.getId(), (System.currentTimeMillis() - startTime));
            }

            return new ApiResult<>(Constants.RESULT_OK_CODE, Constants.RESULT_OK_MSG, result);
            
        } catch (Exception e) {
            log.error("生成审计取证单失败", e);
            return new ApiResult<>(1, "生成审计取证单失败: " + e.getMessage());
//            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 AuditEvidence callWorkflow(JSONObject requestBody) {
        try {
            log.info("调用审计取证单工作流，请求体长度: {}", 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("审计取证单工作流返回结果长度: {}", result.length());

            JSONObject jsonResponse = JSONObject.parseObject(result);

            // 提取输出文本
            String outputText = jsonResponse.getJSONObject("data")
                    .getJSONObject("outputs")
                    .getString("result");

            if (StrUtil.isBlank(outputText)) {
                log.warn("审计取证单工作流返回结果为空");
                return null;
            }

            // 解析为JSON对象
            AuditEvidence auditEvidence = JSONObject.parseObject(outputText, AuditEvidence.class);

            log.info("成功解析审计取证单工作流返回数据");
            return auditEvidence;

        } catch (Exception e) {
            log.error("调用审计取证单工作流失败", e);
            throw new RuntimeException("调用审计取证单工作流失败: " + e.getMessage(), e);
        }
    }

    /**
     * 保存审计取证单到数据库
     */
    /*private void saveToDatabase(AuditEvidence auditEvidence, AuditEvidenceRequest request) {
        try {
//            AuditEvidence auditEvidence = new AuditEvidence();

            // 基本信息
            auditEvidence.setAuditMatterType(request.getAuditMaterType());
            auditEvidence.setContentType(request.getContentType());
            auditEvidence.setCaseIndex(request.getCaseIndex());
            auditEvidence.setProjectId(request.getProjectId());
            auditEvidence.setProjectName(request.getProjectName());
            auditEvidence.setData(request.getHistory());
//            auditEvidence.setAuditedTarget(result.getString("auditedTarget"));
//            auditEvidence.setAuditMatter(result.getString("auditMatter"));
//            auditEvidence.setSummaryTitle(result.getString("summaryTitle"));
            
            // 审计内容
//            auditEvidence.setAuditRecord(result.getString("auditRecord"));
//            auditEvidence.setAuditFinding(result.getString("auditFinding"));
//            auditEvidence.setEvidenceBasis(result.getString("evidenceBasis"));
//            auditEvidence.setHandling(result.getString("handling"));
//            auditEvidence.setSuggestion(result.getString("suggestion"));
//            auditEvidence.setAttachment(result.getString("attachment"));
            
            // 时间和人员信息
//            auditEvidence.setAuditors(result.getString("auditors"));
//            auditEvidence.setCompileDate(result.getString("compileDate"));
//            auditEvidence.setProviderOpinion(result.getString("providerOpinion"));
//            auditEvidence.setProviderDate(result.getString("providerDate"));
//            auditEvidence.setAttachmentPages(result.getString("attachmentPages"));
//            auditEvidence.setFeedbackDeadline(result.getString("feedbackDeadline"));
            
            // 用户信息
            auditEvidence.setUserId(request.getUserId());
            auditEvidence.setUsername(request.getUserName());
            auditEvidence.setTenantId(request.getTenantId());
            
            // 状态信息
            auditEvidence.setStatus(0); // 正常状态
            auditEvidence.setDeleted(0); // 未删除
            
            // 保存到数据库
            baseMapper.insert(auditEvidence);
            
//            log.info("审计取证单保存成功 - ID: {}", auditEvidence.getId());
//            return auditEvidence;
            
        } catch (Exception e) {
            log.error("保存审计取证单到数据库失败", e);
            throw new RuntimeException("保存审计取证单到数据库失败: " + e.getMessage(), e);
        }
    }*/

    @Override
    public PageResult<AuditEvidence> getAuditEvidencePage(PageParam<AuditEvidence, AuditEvidenceParam> page, AuditEvidenceParam param) {
        log.info("查询审计取证单分页列表 - 页码: {}, 页面大小: {}", page.getCurrent(), page.getSize());
        
        try {
            // 调用Mapper的分页查询方法
            IPage<AuditEvidence> list = baseMapper.selectPageRel(page, param);
            
            log.info("审计取证单分页查询成功 - 总记录数: {}, 当前页记录数: {}", 
                    page.getTotal(), list.getTotal());
            
            // 返回分页结果
            return new PageResult<>(list.getRecords(), page.getTotal());
            
        } catch (Exception e) {
            log.error("查询审计取证单分页列表失败", e);
            throw new RuntimeException("查询审计取证单分页列表失败：" + e.getMessage(), e);
        }
    }

    @Override
    public ApiResult<AuditEvidence> saveAuditEvidence(AuditEvidenceRequest request) {
        log.info("开始保存审计取证单 - 用户：{}, 项目：{}", request.getUserName(), request.getProjectName());
        
        try {
            // 1. 验证并转换 auditMatterType
            if (StrUtil.isBlank(request.getAuditMatterType())) {
                return new ApiResult<>(1, "审计事项类型不能为空");
            }
            
            AuditMatterTypeEnum matterType = AuditMatterTypeEnum.getByCode(request.getAuditMatterType());
            if (matterType == null) {
                return new ApiResult<>(1, "无效的审计事项类型：" + request.getAuditMatterType());
            }
            
            // 2. 检查是否已存在（根据 projectId + auditMatterType）
            if (request.getProjectId() == null) {
                return new ApiResult<>(1, "项目编号不能为空");
            }
            
            LambdaQueryWrapper<AuditEvidence> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(AuditEvidence::getProjectId, request.getProjectId())
                       .eq(AuditEvidence::getAuditMatterType, request.getAuditMatterType())
                       .eq(AuditEvidence::getDeleted, 0);
            
            AuditEvidence existingEvidence = baseMapper.selectOne(queryWrapper);
            
            AuditEvidence auditEvidence;
            if (existingEvidence != null) {
                // 3. 更新现有记录
                log.info("发现已存在的记录，执行更新操作 - ID: {}", existingEvidence.getId());
                auditEvidence = existingEvidence;
                
                // 更新字段
                auditEvidence.setCaseIndex(request.getCaseIndex());
                auditEvidence.setProjectName(request.getProjectName());
                auditEvidence.setContentType(request.getContentType());
                
                // 审计内容
                auditEvidence.setSummaryTitle(request.getSummaryTitle());
                auditEvidence.setAuditRecord(request.getAuditRecord());
                auditEvidence.setAuditFinding(request.getAuditFinding());
                auditEvidence.setEvidenceBasis(request.getEvidenceBasis());
                auditEvidence.setHandling(request.getHandling());
                auditEvidence.setSuggestion(request.getSuggestion());
                auditEvidence.setAttachment(request.getAttachment());
                
                // 时间和人员信息
                auditEvidence.setAuditors(request.getAuditors());
                auditEvidence.setCompileDate(request.getCompileDate());
                auditEvidence.setProviderOpinion(request.getProviderOpinion());
                auditEvidence.setProviderDate(request.getProviderDate());
                
                // 处理附件页数（转换为 Integer）
                if (request.getAttachmentPages() != null && !request.getAttachmentPages().isEmpty()) {
                    try {
                        auditEvidence.setAttachmentPages(Integer.parseInt(request.getAttachmentPages()));
                    } catch (NumberFormatException e) {
                        log.warn("附件页数转换失败，使用默认值 0", e);
                        auditEvidence.setAttachmentPages(0);
                    }
                } else {
                    auditEvidence.setAttachmentPages(0);
                }
                
                auditEvidence.setFeedbackDeadline(request.getFeedbackDeadline());
                
                // 将原始数据保存为 JSON 字符串
                auditEvidence.setData(com.alibaba.fastjson.JSONObject.toJSONString(request));
                
                // 更新数据库
                baseMapper.updateById(auditEvidence);
                
                log.info("审计取证单更新成功 - ID: {}", auditEvidence.getId());
            } else {
                // 4. 新增记录
                log.info("未发现已存在的记录，执行新增操作");
                auditEvidence = new AuditEvidence();
                
                // 基本信息
                auditEvidence.setCaseIndex(request.getCaseIndex());
                auditEvidence.setProjectId(request.getProjectId());
                auditEvidence.setProjectName(request.getProjectName());
                auditEvidence.setContentType(request.getContentType());
                auditEvidence.setAuditMatterType(request.getAuditMatterType());
                auditEvidence.setAuditMatter(request.getAuditMatter());
                
                // 审计内容
                auditEvidence.setSummaryTitle(request.getSummaryTitle());
                auditEvidence.setAuditRecord(request.getAuditRecord());
                auditEvidence.setAuditFinding(request.getAuditFinding());
                auditEvidence.setEvidenceBasis(request.getEvidenceBasis());
                auditEvidence.setHandling(request.getHandling());
                auditEvidence.setSuggestion(request.getSuggestion());
                auditEvidence.setAttachment(request.getAttachment());
                
                // 时间和人员信息
                auditEvidence.setAuditors(request.getAuditors());
                auditEvidence.setCompileDate(request.getCompileDate());
                auditEvidence.setProviderOpinion(request.getProviderOpinion());
                auditEvidence.setProviderDate(request.getProviderDate());
                
                // 处理附件页数（转换为 Integer）
                if (request.getAttachmentPages() != null && !request.getAttachmentPages().isEmpty()) {
                    try {
                        auditEvidence.setAttachmentPages(Integer.parseInt(request.getAttachmentPages()));
                    } catch (NumberFormatException e) {
                        log.warn("附件页数转换失败，使用默认值 0", e);
                        auditEvidence.setAttachmentPages(0);
                    }
                } else {
                    auditEvidence.setAttachmentPages(0);
                }
                
                auditEvidence.setFeedbackDeadline(request.getFeedbackDeadline());
                
                // 将原始数据保存为 JSON 字符串
                auditEvidence.setData(com.alibaba.fastjson.JSONObject.toJSONString(request));
                
                // 用户信息
                auditEvidence.setUserId(request.getUserId());
                auditEvidence.setUsername(request.getUserName());
                auditEvidence.setTenantId(request.getTenantId());
                
                // 状态信息
                auditEvidence.setStatus(0); // 正常状态
                auditEvidence.setDeleted(0); // 未删除
                
                // 保存到数据库
                baseMapper.insert(auditEvidence);
                
                log.info("审计取证单保存成功 - ID: {}", auditEvidence.getId());
            }
            
            return new ApiResult<>(Constants.RESULT_OK_CODE, Constants.RESULT_OK_MSG, auditEvidence);
            
        } catch (Exception e) {
            log.error("保存审计取证单到数据库失败", e);
            return new ApiResult<>(1, "保存审计取证单失败：" + e.getMessage());
        }
    }
}