package com.gxwebsoft.ai.controller;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.ai.config.TemplateConfig;
import com.gxwebsoft.ai.dto.AuditReportRequest;
import com.gxwebsoft.ai.dto.KnowledgeBaseRequest;
import com.gxwebsoft.ai.enums.AuditReportEnum;
import com.gxwebsoft.ai.service.KnowledgeBaseService;
import com.gxwebsoft.ai.util.AuditReportUtil;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.User;

import cn.afterturn.easypoi.word.WordExportUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * 审计报告控制器
 * @author GIIT-YC
 *
 */
@Tag(name = "审计报告")
@RestController
@RequestMapping("/api/ai/auditReport")
public class AuditReportController extends BaseController {
    
    @Autowired
    private TemplateConfig templateConfig;
    
    @Autowired
    private KnowledgeBaseService knowledgeBaseService;
    
    private String invok(String query, String knowledge, String history, String suggestion, String title, String userName) {
        // 构建请求体
        JSONObject requestBody = new JSONObject();
        JSONObject inputs = new JSONObject();
        inputs.put("query", query);
        inputs.put("knowledge", knowledge);
        inputs.put("history", history);
        inputs.put("suggestion", suggestion);
        inputs.put("title", title);
        
        requestBody.put("inputs", inputs);
        requestBody.put("response_mode", "blocking");
        requestBody.put("user", userName);
        
        // 发送 POST 请求
        String result = HttpUtil.createPost("http://1.14.159.185:8180/v1/workflows/run")
                .header("Authorization", "Bearer app-d7Ok9FECVZG2Ybw9wpg7tGu9")
                .header("Content-Type", "application/json")
                .body(requestBody.toString())
                .timeout(600000)
                .execute()
                .body();
        // 解析返回的JSON字符串
        JSONObject jsonResponse = JSONObject.parseObject(result);
        // 获取data字段
        JSONObject data = jsonResponse.getJSONObject("data");
        // 获取outputs字段
        JSONObject outputs = data.getJSONObject("outputs");
        // 获取outputs中的result字符串
        String resultStr = outputs.getString("result");
        return resultStr;
    }
    
    /**
     * 生成审计报告-单一模块
     */
    @Operation(summary = "生成审计报告-单一模块")
    @PostMapping("/generate")
    public ApiResult<?> generateAuditReport(@RequestBody AuditReportRequest req) {
    	final User loginUser = getLoginUser();
    	
    	Set<String> kbIdSet = new HashSet<>();
    	List<String> kbIdList = StrUtil.split(req.getKbIds(), ',');
    	for(String kbId : kbIdList) {
    		KnowledgeBaseRequest knowledgeBaseRequest = new KnowledgeBaseRequest();
    		knowledgeBaseRequest.setKbId(kbId);
    		//召回切片数上限
    		knowledgeBaseRequest.setTopK(100);
    		knowledgeBaseRequest.setFormCommit((req.getFormCommit() >= 10) ? req.getFormCommit() / 10 : req.getFormCommit());
    		kbIdSet.addAll(knowledgeBaseService.queryKnowledgeBase(knowledgeBaseRequest));
    	}
    	String knowledge = kbIdSet.toString();
    	
    	String query = AuditReportEnum.getByCode(req.getFormCommit()).getDesc();
//    	String ret = this.invok(query, knowledge, AuditReportUtil.generateReportContent(req), req.getSuggestion(), loginUser.getUsername());
    	String ret = this.invok(query, knowledge, AuditReportUtil.generateReportContentByFormCommit(req), req.getSuggestion(), req.getFrom00(), loginUser.getUsername());
    	
    	return success(ret);
    }
    
    /**
     * 生成并下载审计报告
     */
    @Operation(summary = "生成并下载审计报告")
    @PostMapping("/download")
    public void downloadAuditReport(@RequestBody AuditReportRequest req, HttpServletResponse response) {
        double originalMinInflateRatio = ZipSecureFile.getMinInflateRatio();

        try {
            ZipSecureFile.setMinInflateRatio(0.001);

            // 准备模板数据
            Map<String, Object> map = new HashMap<>();
            map.put(AuditReportEnum.TITLE.getCodeStr(), req.getFrom00());
            map.put(AuditReportEnum.BASIS.getCodeStr(), req.getFrom10());
            map.put(AuditReportEnum.OBJECTIVE.getCodeStr(), req.getFrom20());
            map.put(AuditReportEnum.SCOPE.getCodeStr(), req.getFrom30());
            map.put(AuditReportEnum.UNIT_OVERVIEW.getCodeStr(), req.getFrom41());
            map.put(AuditReportEnum.ORG_PERSONNEL.getCodeStr(), req.getFrom42());
            map.put(AuditReportEnum.FINANCIAL_ACCOUNTING.getCodeStr(), req.getFrom43());
            map.put(AuditReportEnum.ANNUAL_BUSINESS.getCodeStr(), req.getFrom44());
            map.put(AuditReportEnum.INTERNAL_CONTROL.getCodeStr(), req.getFrom45());
            map.put(AuditReportEnum.ECONOMIC_POLICIES.getCodeStr(), req.getFrom51());
            map.put(AuditReportEnum.DEV_STRATEGY.getCodeStr(), req.getFrom52());
            map.put(AuditReportEnum.MAJOR_ECONOMIC.getCodeStr(), req.getFrom53());
            map.put(AuditReportEnum.CORP_GOVERNANCE.getCodeStr(), req.getFrom54());
            map.put(AuditReportEnum.FINANCIAL_LEGAL.getCodeStr(), req.getFrom55());
            map.put(AuditReportEnum.INTEGRITY_COMPLIANCE.getCodeStr(), req.getFrom56());
            map.put(AuditReportEnum.PREV_AUDIT_ISSUES.getCodeStr(), req.getFrom57());
            map.put(AuditReportEnum.OTHER_MATTERS.getCodeStr(), req.getFrom58());
            map.put(AuditReportEnum.RISK_IDENTIFY.getCodeStr(), req.getFrom61());
            map.put(AuditReportEnum.RISK_RESPONSE.getCodeStr(), req.getFrom62());
            map.put(AuditReportEnum.TECHNIQUES.getCodeStr(), req.getFrom70());
            map.put(AuditReportEnum.SCHEDULE.getCodeStr(), req.getFrom80());
            map.put(AuditReportEnum.ORGANIZATION.getCodeStr(), req.getFrom90());

            // 使用 Easypoi 的 Word 模板功能
            XWPFDocument document = WordExportUtil.exportWord07(templateConfig.getWordTemplatePath(), map);

            // 处理换行，确保 \n 转为硬回车（新段落）
            processParagraphs(document);

            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            response.setHeader("Content-Disposition", "attachment; filename=audit_report.docx");

            try (OutputStream out = response.getOutputStream()) {
                document.write(out);
                out.flush();
            }

        } catch (Exception e) {
            throw new RuntimeException("生成审计报告失败", e);
        } finally {
            ZipSecureFile.setMinInflateRatio(originalMinInflateRatio);
        }
    }

    private void processParagraphs(XWPFDocument document) {
        List<XWPFParagraph> originalParas = new ArrayList<>(document.getParagraphs());

        for (XWPFParagraph para : originalParas) {
            String text = para.getText();
            if (text == null || !text.contains("\n")) {
                continue;
            }

            String[] parts = text.replace("\r\n", "\n").replace("\r", "\n").split("\n");
            
            // 在原段落位置之前插入新段落
            int pos = document.getPosOfParagraph(para);
            
            // 修正：按正序插入（从前往后）
            for (int i = 0; i < parts.length; i++) {
                // 创建新段落
                XWPFParagraph newPara = document.insertNewParagraph(para.getCTP().newCursor());
                
                // 复制样式
                newPara.getCTP().setPPr(para.getCTP().getPPr());
                
                XWPFRun newRun = newPara.createRun();
                newRun.setText(parts[i].trim());
                
                if (!para.getRuns().isEmpty()) {
                    newRun.getCTR().setRPr(para.getRuns().get(0).getCTR().getRPr());
                }
            }
            
            // 删除原段落
            document.removeBodyElement(pos + parts.length);
        }
    }

}
