package com.gxwebsoft.ai.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gxwebsoft.ai.dto.AuditContentRequest;
import com.gxwebsoft.ai.dto.export.TripleOneExportEntity;
import com.gxwebsoft.ai.dto.export.DecisionTableExportEntity;
import com.gxwebsoft.ai.entity.AiCloudDoc;
import com.gxwebsoft.ai.entity.AiCloudFile;
import com.gxwebsoft.ai.service.AiHistoryService;
import com.gxwebsoft.ai.utils.ExcelExportTool;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.pwl.entity.PwlProjectLibrary;
import com.gxwebsoft.pwl.service.PwlProjectLibraryService;
import com.gxwebsoft.ai.service.AiCloudDocService;
import com.gxwebsoft.ai.service.AiCloudFileService;
import com.gxwebsoft.ai.service.AuditContent3TripleService;
import com.gxwebsoft.ai.service.AuditContent3DecisionService;
import com.gxwebsoft.ai.service.KnowledgeBaseService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 审计内容3控制器 - 三重一大制度对比分析 & 重大经济决策调查表
 */
@Slf4j
@Tag(name = "审计内容3-三重一大制度")
@RestController
@RequestMapping("/api/ai/auditContent3")
public class AuditContent3Controller extends BaseController {
    
    @Autowired
    private AuditContent3TripleService auditContent3TripleService;
    
    @Autowired
    private AuditContent3DecisionService auditContent3DecisionService;
    
    @Autowired
    private AiCloudDocService aiCloudDocService;
    
    @Autowired
    private AiCloudFileService aiCloudFileService;
    
    @Autowired
    private KnowledgeBaseService knowledgeBaseService;
    
    @Autowired
    private PwlProjectLibraryService pwlProjectLibraryService;
    
    @Autowired
    private AiHistoryService aiHistoryService;
    
    // 历史记录有效期（分钟）
    private static final int HISTORY_EXPIRE_MINUTES = 10;
    
    /**
     * 生成三重一大制度对比分析表数据
     */
    @Operation(summary = "生成三重一大制度对比分析表")
    @PostMapping("/generateTripleOneTable")
    public ApiResult<?> generateTripleOneTable(@RequestBody AuditContentRequest request, HttpServletRequest servletRequest) {
        return generateTableData(request, servletRequest.getRequestURI(), 
            (params) -> auditContent3TripleService.generateTripleOneTableData(
                params.knowledgeBaseId, params.libraryKbIds, params.projectLibrary,
                params.username, params.history, params.suggestion
            ));
    }
    
    /**
     * 生成重大经济决策调查表数据
     */
    @Operation(summary = "生成重大经济决策调查表")
    @PostMapping("/generateDecisionTable")
    public ApiResult<?> generateDecisionTable(@RequestBody AuditContentRequest request, HttpServletRequest servletRequest) {
        return generateTableData(request, servletRequest.getRequestURI(), 
            (params) -> auditContent3DecisionService.generateDecisionTableData(
                params.knowledgeBaseId, params.libraryKbIds, params.projectLibrary,
                params.username, params.history, params.suggestion, request.getData()
            ));
    }
    
    /**
     * 通用的表格数据生成方法
     */
    private ApiResult<?> generateTableData(AuditContentRequest request, String interfaceName, Function<GenerateParams, JSONObject> generateFunction) {
        final User loginUser = getLoginUser();
        String requestHistory = request.getHistory();
        request.setHistory("");
        
        // 检查历史记录
        String requestHash = generateRequestHash(request, interfaceName);
        var history = aiHistoryService.getValidHistory(requestHash, interfaceName, HISTORY_EXPIRE_MINUTES);
        if (history != null) {
            log.info("返回历史数据，请求哈希: {}", requestHash);
            return success(JSONObject.parseObject(history.getResponseData()));
        }
        request.setHistory(requestHistory);
        
        String kbIdTmp = "";
        String libraryKbIds = "";
        
        try {
            // 创建临时知识库（如果需要）
            if (hasUploadedFiles(request)) {
                kbIdTmp = createTempKnowledgeBase(request);
            }
            
            // 查询项目库信息
            libraryKbIds = getLibraryKbIds(request.getLibraryIds());
            
            // 生成数据
            String knowledgeBaseId = getKnowledgeBaseId(kbIdTmp, request.getKbIds());
            GenerateParams params = new GenerateParams(knowledgeBaseId, libraryKbIds, request.getProjectLibrary(), loginUser.getUsername(), request.getHistory(), request.getSuggestion());
            
            JSONObject result = generateFunction.apply(params);
            
            if(result.getBoolean("success")) {
            	// 保存到历史记录
            	saveToHistory(request, interfaceName, requestHash, result, loginUser);
            }
            
            return success(result);
        } catch (Exception e) {
            log.error("生成表格数据失败，接口: {}", interfaceName, e);
            return fail("生成表格数据失败: " + e.getMessage());
        } finally {
            cleanupTempKnowledgeBase(kbIdTmp);
        }
    }
    
    /**
     * 生成请求哈希
     */
    private String generateRequestHash(AuditContentRequest request, String interfaceName) {
        String requestJson = JSONObject.toJSONString(request);
        return DigestUtil.md5Hex(interfaceName + ":" + requestJson);
    }
    
    /**
     * 保存到历史记录
     */
    private void saveToHistory(AuditContentRequest request, String interfaceName, String requestHash, JSONObject result, User loginUser) {
        try {
            aiHistoryService.saveHistory(requestHash, interfaceName, JSONObject.toJSONString(request), result.toJSONString(), loginUser.getUserId(), loginUser.getUsername(), loginUser.getTenantId());
        } catch (Exception e) {
            log.warn("保存历史记录失败", e);
        }
    }
    
    /**
     * 检查是否有上传的文件
     */
    private boolean hasUploadedFiles(AuditContentRequest request) {
        return !request.getDocList().isEmpty() || !request.getFileList().isEmpty();
    }
    
    /**
     * 获取知识库ID
     */
    private String getKnowledgeBaseId(String tempKbId, String requestKbIds) {
        return StrUtil.isNotBlank(tempKbId) ? tempKbId : requestKbIds;
    }
    
    /**
     * 获取项目库KB IDs
     */
    private String getLibraryKbIds(String libraryIds) {
        if (StrUtil.isBlank(libraryIds)) {
            return "";
        }
        List<String> idList = StrUtil.split(libraryIds, ',');
        List<PwlProjectLibrary> ret = pwlProjectLibraryService.list(new LambdaQueryWrapper<PwlProjectLibrary>().in(PwlProjectLibrary::getId, idList));
        return ret.stream().map(PwlProjectLibrary::getKbId).filter(StrUtil::isNotBlank).collect(Collectors.joining(","));
    }
    
    /**
     * 创建临时知识库并提交文档
     */
    private String createTempKnowledgeBase(AuditContentRequest request) {
        String kbIdTmp = knowledgeBaseService.createKnowledgeBaseTemp();
        // 收集文档ID
        Set<Integer> docIds = request.getDocList().stream().flatMap(docId -> aiCloudDocService.getSelfAndChildren(docId).stream()).map(AiCloudDoc::getId).collect(Collectors.toSet());
        // 查询相关文件
        List<AiCloudFile> fileList = getRelatedFiles(docIds, request.getFileList());
        // 提取文件ID并提交到知识库
        Set<String> kbFileIds = fileList.stream().map(AiCloudFile::getFileId).collect(Collectors.toSet());
        if (!kbFileIds.isEmpty()) {
            knowledgeBaseService.submitDocuments(kbIdTmp, new ArrayList<>(kbFileIds));
        }
        return kbIdTmp;
    }
    
    /**
     * 获取相关文件列表
     */
    private List<AiCloudFile> getRelatedFiles(Set<Integer> docIds, List<Integer> fileList) {
        LambdaQueryWrapper<AiCloudFile> queryWrapper = new LambdaQueryWrapper<AiCloudFile>()
                .in(!docIds.isEmpty(), AiCloudFile::getDocId, docIds)
                .or(!fileList.isEmpty())
                .in(!fileList.isEmpty(), AiCloudFile::getId, fileList);
        return aiCloudFileService.list(queryWrapper);
    }
    
    /**
     * 清理临时知识库
     */
    private void cleanupTempKnowledgeBase(String kbId) {
        if (StrUtil.isNotBlank(kbId)) {
            try {
                knowledgeBaseService.deleteIndex(kbId);
            } catch (Exception e) {
                log.warn("删除临时知识库失败: {}", kbId, e);
            }
        }
    }
    
    /**
     * 导出三重一大制度对比分析表到Excel
     */
    @Operation(summary = "导出三重一大制度对比分析表到Excel")
    @PostMapping("/exportTripleOneTable")
    public void exportTripleOneTable(@RequestBody Map<String, Object> request, HttpServletResponse response) {
        exportToExcel(request, response, "三重一大制度对比分析表", 
            this::convertToTripleOneEntityList, TripleOneExportEntity.class);
    }
    
    /**
     * 导出重大经济决策调查表到Excel
     */
    @Operation(summary = "导出重大经济决策调查表到Excel")
    @PostMapping("/exportDecisionTable")
    public void exportDecisionTable(@RequestBody Map<String, Object> request, HttpServletResponse response) {
        exportToExcel(request, response, "重大经济决策调查表", 
            this::convertToDecisionTableEntityList, DecisionTableExportEntity.class);
    }
    
    /**
     * 通用的Excel导出方法
     */
    private <T> void exportToExcel(Map<String, Object> request, HttpServletResponse response, 
                                  String sheetName, Function<List<Map<String, Object>>, List<T>> converter, 
                                  Class<T> entityClass) {
        List<Map<String, Object>> dataList = (List<Map<String, Object>>) request.get("data");
        String companyName = (String) request.get("companyName");
        
        List<T> exportData = converter.apply(dataList);
        
        String fileName = sheetName + "_" + (companyName != null ? companyName : "未知公司");
        String title = companyName != null ? companyName + " - " + sheetName : sheetName;
        
        ExcelExportTool.exportExcel(exportData, entityClass, fileName, sheetName, title, response);
    }
    
    /**
     * 参数包装类
     */
    private static class GenerateParams {
        final String knowledgeBaseId;
        final String libraryKbIds;
        final String projectLibrary;
        final String username;
        final String history;
        final String suggestion;
        
        GenerateParams(String knowledgeBaseId, String libraryKbIds, String projectLibrary, String username, String history, String suggestion) {
            this.knowledgeBaseId = knowledgeBaseId;
            this.libraryKbIds = libraryKbIds;
            this.projectLibrary = projectLibrary;
            this.username = username;
            this.history = history;
            this.suggestion = suggestion;
        }
    }
    
    // ========== 数据转换方法 ==========
    
    private List<TripleOneExportEntity> convertToTripleOneEntityList(List<Map<String, Object>> originalData) {
        return originalData.stream().map(this::convertToTripleOneEntity).collect(Collectors.toList());
    }
    
    private List<DecisionTableExportEntity> convertToDecisionTableEntityList(List<Map<String, Object>> originalData) {
        return originalData.stream().map(this::convertToDecisionTableEntity).collect(Collectors.toList());
    }
    
    private TripleOneExportEntity convertToTripleOneEntity(Map<String, Object> item) {
        TripleOneExportEntity entity = new TripleOneExportEntity();
        entity.setCategory(getStringValue(item, "category"));
        entity.setPolicyContent(getStringValue(item, "policyContent"));
        entity.setGroupSystem(getStringValue(item, "groupSystem"));
        entity.setCompanyFormulation(getStringValue(item, "companyFormulation"));
        entity.setCheckEvidence(getStringValue(item, "checkEvidence"));
        entity.setTestResult(getStringValue(item, "testResult"));
        entity.setWorkPaperIndex(formatWorkPaperIndex(item.get("workPaperIndex")));
        return entity;
    }
    
    private DecisionTableExportEntity convertToDecisionTableEntity(Map<String, Object> item) {
        DecisionTableExportEntity entity = new DecisionTableExportEntity();
        entity.setIndex(getStringValue(item, "index"));
        entity.setDecisionItem(getStringValue(item, "name"));
        entity.setMeetingTime(getStringValue(item, "meetingTime"));
        entity.setDecisionAmount(getStringValue(item, "decisionAmount"));
        entity.setProcedure(getStringValue(item, "procedure"));
        entity.setExecutionStatus(getStringValue(item, "executionStatus"));
        entity.setGood(getStringValue(item, "goods"));
        entity.setNormal(getStringValue(item, "normal"));
        entity.setBad(getStringValue(item, "bad"));
        return entity;
    }
    
    private String getStringValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value != null ? value.toString() : "";
    }
    
    private String formatWorkPaperIndex(Object workPaperIndex) {
        if (workPaperIndex == null) {
            return "";
        }
        
        if (workPaperIndex instanceof List) {
            List<?> list = (List<?>) workPaperIndex;
            return String.join(", ", list.stream()
                    .map(Object::toString)
                    .collect(Collectors.toList()));
        }
        
        return workPaperIndex.toString();
    }
}