package com.gxwebsoft.ai.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gxwebsoft.ai.dto.AuditContentRequest;
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.KnowledgeBaseService;
import com.gxwebsoft.ai.service.impl.AbstractAuditContentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
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;

/**
 * 审计内容基础控制器
 */
@Slf4j
public abstract class BaseAuditContentController extends BaseController {
    
    @Autowired
    protected AiCloudDocService aiCloudDocService;
    
    @Autowired
    protected AiCloudFileService aiCloudFileService;
    
    @Autowired
    protected KnowledgeBaseService knowledgeBaseService;
    
    @Autowired
    protected PwlProjectLibraryService pwlProjectLibraryService;
    
    @Autowired
    protected AiHistoryService aiHistoryService;
    
    // 历史记录有效期（分钟）
    protected static final int HISTORY_EXPIRE_MINUTES = 10;
    
    /**
     * 通用的表格数据生成方法
     */
    protected 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 libraryKbIds = "";
        
        try {
            // 查询项目库信息
            libraryKbIds = getLibraryKbIds(request.getLibraryIds());
            
            // 如果有docList/fileList，计算去重的fileIds并设置到ThreadLocal
            if (hasUploadedFiles(request)) {
                Set<Integer> docIds = request.getDocList().stream().flatMap(docId -> aiCloudDocService.getSelfAndChildren(docId).stream()).map(AiCloudDoc::getId).collect(Collectors.toSet());
                List<AiCloudFile> relatedFiles = getRelatedFiles(docIds, request.getFileList());
                List<String> fileIds = relatedFiles.stream().map(AiCloudFile::getFileId).distinct().collect(Collectors.toList());
                Set<String> mainKbIds = Arrays.stream(request.getKbIds().split(",")).map(String::trim).filter(StrUtil::isNotBlank).collect(Collectors.toSet());
                AbstractAuditContentService.setRequestFileIds(mainKbIds, fileIds);
            }
            
            // 生成数据（使用原来的默认知识库）
            GenerateParams params = new GenerateParams(request.getKbIds(), libraryKbIds, request.getProjectLibrary(), loginUser.getUsername(), request.getHistory(), request.getSuggestion());
            
            JSONObject result = generateFunction.apply(params);
            
            if(result.getBoolean("success")) {
            	// 转换workPaperIndex，原数据：["文件名1"+"||"+"下载地址1","文件名2"+"||"+"下载地址2"]，转换后：["文件ID1"+"||"+"文件名1"+"||"+"下载地址1","文件ID2"+"||"+"文件名2"+"||"+"下载地址2"]
            	convertWorkPaperFileInfo(result);
                // 保存到历史记录
                saveToHistory(request, interfaceName, requestHash, result, loginUser);
            }
            
            return success(result);
        } catch (Exception e) {
            log.error("生成表格数据失败，接口: {}", interfaceName, e);
            return fail("生成表格数据失败: " + e.getMessage());
        } finally {
            AbstractAuditContentService.clearRequestFileIds();
        }
    }
    
    private void convertWorkPaperFileInfo(JSONObject result) {
        JSONArray data = result.getJSONArray("data");
        for (int i = 0; i < data.size(); i++) {
            JSONObject obj = data.getJSONObject(i);
            JSONArray workPaperIndexFiles = obj.getJSONArray("workPaperIndex");
            if (workPaperIndexFiles != null && !workPaperIndexFiles.isEmpty()) {
                for (int j = 0; j < workPaperIndexFiles.size(); j++) {
                    String files = workPaperIndexFiles.getString(j);
                    workPaperIndexFiles.set(j, "FileId||" + files);
                }
            }
        }
    }
    
    private void convertWorkPaperFileInfo2(JSONObject result) {
        JSONArray data = result.getJSONArray("data");
        
        for (int i = 0; i < data.size(); i++) {
            JSONObject obj = data.getJSONObject(i);
            JSONArray workPaperIndexFileIds = obj.getJSONArray("workPaperIndex");
            
            // 先获取并转换 workPaperIndex 字段
            if (workPaperIndexFileIds != null && !workPaperIndexFileIds.isEmpty()) {
                // 先查询所有文件
                List<AiCloudFile> aiCloudFiles = aiCloudFileService.list(new LambdaQueryWrapper<AiCloudFile>().in(AiCloudFile::getFileId, workPaperIndexFileIds));
                
                // 创建文件ID到文件的映射，便于查找
                Map<String, AiCloudFile> fileMap = aiCloudFiles.stream().collect(Collectors.toMap(AiCloudFile::getFileId, file -> file));
                
                // 创建转换后的数组（保持原顺序）
                JSONArray transformedArray = new JSONArray();
                for (Object fileIdObj : workPaperIndexFileIds) {
                    String fileId = (String) fileIdObj;
                    AiCloudFile file = fileMap.get(fileId);
                    if (file != null) {
                        String transformed = file.getFileId() + "||" + file.getFileName() + "||" + file.getFileUrl();
                        transformedArray.add(transformed);
                    } else {
                        transformedArray.add(fileIdObj);
                    }
                }
                
                // 将转换后的数据塞回原字段
                obj.put("workPaperIndex", transformedArray);
                
                // 使用 workPaperIndexFileIds 中的每个 fileId 替换其他字段中的四种格式
                for (String key : obj.keySet()) {
                    if ("workPaperIndex".equals(key)) {
                        continue; // 跳过 workPaperIndex 字段
                    }
                    Object value = obj.get(key);
                    if (value instanceof String) {
                        String text = (String) value;
                        for (Object fileIdObj : workPaperIndexFileIds) {
                            String fileId = (String) fileIdObj;
                            text = text.replace("【FileId:" + fileId + "】", "")
                                       .replace("（FileId:" + fileId + "）", "")
                                       .replace("(FileId:" + fileId + ")", "")
                                       .replace("FileId:"+fileId, "")
                                       .replace("【" + fileId + "】", "")
                                       .replace("（" + fileId + "）", "")
                                       .replace("(" + fileId + ")", "")
                                       .replace(fileId, "");;
                        }
                        obj.put(key, text);
                    }
                }
            }
        }
    }

    
    /**
     * 生成请求哈希
     */
    protected String generateRequestHash(AuditContentRequest request, String interfaceName) {
        String requestJson = JSONObject.toJSONString(request);
        return DigestUtil.md5Hex(interfaceName + ":" + requestJson);
    }
    
    /**
     * 保存到历史记录
     */
    protected void saveToHistory(AuditContentRequest request, String interfaceName, String requestHash, JSONObject result, User loginUser) {
        try {
            aiHistoryService.saveHistory(request.getProjectId(), requestHash, interfaceName, JSONObject.toJSONString(request), result.toJSONString(), loginUser.getUserId(), loginUser.getUsername(), loginUser.getTenantId());
        } catch (Exception e) {
            log.warn("保存历史记录失败", e);
        }
    }
    
    /**
     * 检查是否有上传的文件
     */
    protected boolean hasUploadedFiles(AuditContentRequest request) {
        List<Integer> docList = request.getDocList();
        List<Integer> fileList = request.getFileList();
        return (docList != null && !docList.isEmpty()) || (fileList != null && !fileList.isEmpty());
    }
    
    /**
     * 获取知识库ID
     */
    protected String getKnowledgeBaseId(String tempKbId, String requestKbIds) {
        return StrUtil.isNotBlank(tempKbId) ? tempKbId : requestKbIds;
    }
    
    /**
     * 获取项目库KB IDs
     */
    protected 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(","));
    }
    
    /**
     * 创建临时知识库并提交文档
     */
    protected 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;
    }
    
    /**
     * 获取相关文件列表
     */
    protected 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);
    }
    
    /**
     * 清理临时知识库
     */
    protected void cleanupTempKnowledgeBase(String kbId) {
        if (StrUtil.isNotBlank(kbId)) {
            try {
                knowledgeBaseService.deleteIndex(kbId);
            } catch (Exception e) {
                log.warn("删除临时知识库失败: {}", kbId, e);
            }
        }
    }
    
    /**
     * 通用的Excel导出方法
     */
    protected <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);
    }
    
    /**
     * 带审计时间的Excel导出方法
     */
    protected <T> void exportToExcelWithAuditTime(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");
        String auditTime = (String) request.get("auditTime");
        
        List<T> exportData = converter.apply(dataList);
        
        String fileName = sheetName + "_" + (companyName != null ? companyName : "未知公司");
        String title = companyName != null ? companyName + " - " + sheetName : sheetName;
        
        if (auditTime != null) {
            title += "（审计时间：" + auditTime + "）";
        }
        
        ExcelExportTool.exportExcel(exportData, entityClass, fileName, sheetName, title, response);
    }
    
    /**
     * 参数包装类
     */
    protected static class GenerateParams {
        public final String knowledgeBaseId;
        public final String libraryKbIds;
        public final String projectLibrary;
        public final String username;
        public final String history;
        public final String suggestion;
        
        public 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;
        }
    }
    
    // ========== 通用的工具方法 ==========
    
    /**
     * 获取字符串值
     */
    protected String getStringValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value != null ? value.toString() : "";
    }
    
    /**
     * 格式化底稿索引
     */
    protected 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();
    }
}