package com.hotent.util.wordexcelutils;

import org.apache.poi.xwpf.usermodel.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.*;

/**
 * 卷宗文书生成测试工具类
 *
 * @company 山西清众科技股份有限公司
 * @author 超级管理员
 * @since 2025-12-08
 */
public class ArchiveDocumentGeneratorTest {

    // 固定模板路径
    private static final String COVER_TEMPLATE_PATH = "D:\\fx\\1、卷宗封面.docx";      // 案卷封面模板
    private static final String CATALOG_TEMPLATE_PATH = "D:\\fx\\2、卷内目录.docx";    // 卷内目录模板
    private static final String BACK_COVER_TEMPLATE_PATH = "D:\\fx\\3.docx"; // 案卷封底模板

    // 输出路径
    private static final String OUTPUT_DIR = "D:\\fx\\output\\";

    public static void main(String[] args) {
        try {
            System.out.println("========== 卷宗文书生成测试 ==========");

            // 测试生成案卷封面
            System.out.println("\n1. 测试生成案卷封面...");
            generateCoverTest();

            // 测试生成卷内目录
            System.out.println("\n2. 测试生成卷内目录...");
            generateCatalogTest();

            // 测试生成案卷封底
//            System.out.println("\n3. 测试生成案卷封底...");
//            generateBackCoverTest();

            System.out.println("\n========== 测试完成 ==========");
            System.out.println("输出目录: " + OUTPUT_DIR);

        } catch (Exception e) {
            System.err.println("测试失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 测试生成案卷封面
     */
    private static void generateCoverTest() throws Exception {
        Map<String, String> replacements = new HashMap<>();
        replacements.put("{价格主管部门或成本监审机构}", "山西省发展和改革委员会");
        replacements.put("{年份}", "2025");
        replacements.put("{卷宗号}", "001");
        replacements.put("{监审项目名称}", "某某供水公司成本监审项目");
        replacements.put("{被监审单位}", "某某供水有限公司");
        replacements.put("{监审开始年度}", "2022");
        replacements.put("{监审结束年度}", "2024");
        replacements.put("{监审组负责人及人员}", "张三、李四、王五");
        replacements.put("{监审办结时间}", "2025年12月");
        replacements.put("{保管期间周期}", "永久");

        String outputPath = OUTPUT_DIR + "案卷封面_测试.docx";
        generateDocument(COVER_TEMPLATE_PATH, outputPath, replacements, 1, null);
        System.out.println("   生成成功: " + outputPath);
    }

    /**
     * 测试生成卷内目录
     * 注意：卷内目录不需要替换占位符，只需要填充表格数据
     */
    private static void generateCatalogTest() throws Exception {
        // 卷内目录不需要替换文档中的占位符，表头的{序号}{资料名称}等是列标题，保持不变
        Map<String, String> replacements = new HashMap<>();

        // 模拟资料列表数据
        List<TableRowData> dataList = new ArrayList<>();
        dataList.add(new TableRowData("成本监审报告（含成本监审报告签发稿、送达回证）", 30, "1-30"));
        dataList.add(new TableRowData("被监审单位申请定（调）价报告（复印件）", 5, "31-35"));
        dataList.add(new TableRowData("成本监审通知书（含送达回证）", 13, "36-48"));
        dataList.add(new TableRowData("经营者需提供成本资料清单", 5, "49-54"));
        dataList.add(new TableRowData("《政府定价成本监审调查表》", 5, "55-60"));
        dataList.add(new TableRowData("成本监审补充资料通知书（含送达回证）", 5, "61-65"));
        dataList.add(new TableRowData("成本审核初步意见告知书（含送达回证）", 5, "66-70"));
        dataList.add(new TableRowData("经营者书面反馈的材料", 1, "71"));
        dataList.add(new TableRowData("成本审核初步意见表（集体审议用）", 1, "72"));
        dataList.add(new TableRowData("成本监审集体审议记录", 2, "73-74"));
        dataList.add(new TableRowData("成本监审工作底稿", 10, "75-84"));
        dataList.add(new TableRowData("成本监审提取资料登记表", 3, "85-87"));
        dataList.add(new TableRowData("提取的成本资料和会计凭证等复印件", 13, "88-100"));

        String outputPath = OUTPUT_DIR + "卷内目录_测试.docx";
        generateDocument(CATALOG_TEMPLATE_PATH, outputPath, replacements, 2, dataList);
        System.out.println("   生成成功: " + outputPath);
    }

    /**
     * 测试生成案卷封底
     */
    private static void generateBackCoverTest() throws Exception {
        Map<String, String> replacements = new HashMap<>();
        replacements.put("{价格主管部门或成本监审机构}", "山西省发展和改革委员会");
        replacements.put("{立卷人}", "张三");
        replacements.put("{立卷日期}", "2025年12月8日");
        replacements.put("{检查人}", "李四");
        replacements.put("{检查日期}", "2025年12月9日");
        replacements.put("{备注}", "无");
        replacements.put("{材料件数}", "13");
        replacements.put("{材料页数}", "100");

        String outputPath = OUTPUT_DIR + "案卷封底_测试.docx";
        generateDocument(BACK_COVER_TEMPLATE_PATH, outputPath, replacements, 3, null);
        System.out.println("   生成成功: " + outputPath);
    }

    /**
     * 生成文书
     *
     * @param templatePath 模板路径
     * @param outputPath   输出路径
     * @param replacements 替换映射
     * @param documentType 文书类型：1-封面 2-目录 3-封底
     * @param dataList     表格数据（仅目录使用）
     */
    private static void generateDocument(String templatePath, String outputPath,
                                          Map<String, String> replacements, int documentType,
                                          List<TableRowData> dataList) throws Exception {
        FileInputStream fis = null;
        XWPFDocument document = null;
        FileOutputStream fos = null;

        try {
            // 检查模板文件是否存在
            java.io.File templateFile = new java.io.File(templatePath);
            if (!templateFile.exists()) {
                System.err.println("   警告: 模板文件不存在 - " + templatePath);
                System.out.println("   跳过此测试，请确保模板文件存在");
                return;
            }

            // 读取模板
            fis = new FileInputStream(templatePath);
            document = new XWPFDocument(fis);

            // 替换占位符
            SmartTemplateWriter.writeToTemplate(document, replacements);

            // 如果是目录，处理表格数据
            if (documentType == 2 && dataList != null && !dataList.isEmpty()) {
                processTableData(document, dataList);
            }

            // 确保输出目录存在
            java.io.File outputFile = new java.io.File(outputPath);
            if (!outputFile.getParentFile().exists()) {
                outputFile.getParentFile().mkdirs();
            }

            // 写入文件
            fos = new FileOutputStream(outputPath);
            document.write(fos);

        } finally {
            // 关闭资源
            try {
                if (fos != null) fos.close();
                if (document != null) document.close();
                if (fis != null) fis.close();
            } catch (Exception e) {
                System.err.println("关闭文件流失败: " + e.getMessage());
            }
        }
    }

    /**
     * 处理目录表格数据
     * 表格结构：第1行表头（{序号}{资料名称}等列标题，保持不变），后面是空行需要填充数据
     */
    private static void processTableData(XWPFDocument document, List<TableRowData> dataList) {
        List<XWPFTable> tables = document.getTables();
        if (tables.isEmpty()) {
            System.err.println("   警告: 未找到表格");
            return;
        }

        XWPFTable table = tables.get(0);
        System.out.println("   原始表格行数: " + table.getRows().size());

        // 第1行是表头（索引0），保持不变
        // 从第2行开始是数据行（索引1）
        int headerRowIndex = 0;
        int dataStartRowIndex = 1;

        XWPFTableRow headerRow = table.getRow(headerRowIndex);
        int cellCount = headerRow.getTableCells().size();
        System.out.println("   表头单元格数: " + cellCount);

        // 删除表头之后的所有行（只保留表头）
        while (table.getRows().size() > 1) {
            table.removeRow(1);
        }

        // 从表头后面开始添加数据行
        for (int i = 0; i < dataList.size(); i++) {
            TableRowData data = dataList.get(i);
            // 创建新行
            XWPFTableRow newRow = table.createRow();
            fillTableRow(newRow, i + 1, data);
        }

        System.out.println("   填充完成，最终行数: " + table.getRows().size());
    }

    /**
     * 填充表格行数据
     */
    private static void fillTableRow(XWPFTableRow row, int sequence, TableRowData data) {
        List<XWPFTableCell> cells = row.getTableCells();
        if (cells.size() >= 4) {
            setCellText(cells.get(0), String.valueOf(sequence));
            setCellText(cells.get(1), data.documentName);
            setCellText(cells.get(2), data.pageCount > 0 ? String.valueOf(data.pageCount) : "");
            setCellText(cells.get(3), data.pageRange != null ? data.pageRange : "");
        }
    }

    /**
     * 设置单元格文本
     */
    private static void setCellText(XWPFTableCell cell, String text) {
        // 清除现有内容
        for (int i = cell.getParagraphs().size() - 1; i >= 0; i--) {
            cell.removeParagraph(i);
        }
        // 添加新内容
        XWPFParagraph paragraph = cell.addParagraph();
        XWPFRun run = paragraph.createRun();
        run.setText(text);
        paragraph.setAlignment(ParagraphAlignment.CENTER);
    }

    /**
     * 表格行数据类
     */
    static class TableRowData {
        String documentName;
        int pageCount;
        String pageRange;

        TableRowData(String documentName, int pageCount, String pageRange) {
            this.documentName = documentName;
            this.pageCount = pageCount;
            this.pageRange = pageRange;
        }
    }
}
