package com.hotent.util.wordexcelutils;/**
 * @program: cbjs-mvue-master
 * @description:
 * @author: zhao yue yue
 * @create: 2025-12-03 11:13
 */

import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;

import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *@author: zhao yue yue
 *@create: 2025-12-03 11:13
 */
public class RobustComplexDocumentProcessor {

    /**
     * 处理复杂文档：使用Map和List作为数据结构
     */
    public static void processDocumentWithMaps(XWPFDocument document,
                                               Map<String, String> textReplacements,
                                               List<String> years,
                                               List<Map<String, Object>> costItems) {

        System.out.println("开始处理文档（Map版）...");

        try {
            // 1. 替换所有文本占位符
            SmartTemplateWriter.writeToTemplate(document,textReplacements);
            //replaceAllTextPlaceholders(document, textReplacements);

            // 2. 处理定价成本核定表
            processCostTableWithMaps(document, years, costItems);
            List<XWPFTable> tables = document.getTables();

            System.out.println("文档处理完成！");

        } catch (Exception e) {
            System.err.println("处理过程中出现错误: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 替换所有文本占位符
     */
    private static void replaceAllTextPlaceholders(XWPFDocument document,
                                                   Map<String, String> replacements) {
        System.out.println("开始替换文本占位符...");

        // 存储替换统计
        Map<String, Boolean> replacementStats = new HashMap<>();

        // 尝试多种替换策略
        for (Map.Entry<String, String> entry : replacements.entrySet()) {
            String placeholder = entry.getKey();
            String value = entry.getValue();

            boolean success = false;

            // 策略1：在段落中直接替换
            success = replaceInParagraphs(document, placeholder, value);

            // 策略2：在表格中替换
            if (!success) {
                success = replaceInTables(document, placeholder, value);
            }

            // 策略3：使用智能替换
            if (!success) {
                success = smartReplaceInDocument(document, placeholder, value);
            }

            replacementStats.put(placeholder, success);

            String status = success ? "✅" : "❌";
            System.out.println(status + " " + placeholder + " → " + value +
                    (success ? "" : " (未找到)"));
        }

        // 打印替换统计
        long successCount = replacementStats.values().stream().filter(v -> v).count();
        long totalCount = replacementStats.size();
        System.out.println("替换完成: " + successCount + "/" + totalCount + " 个占位符");
    }

    /**
     * 在段落中替换
     */
    private static boolean replaceInParagraphs(XWPFDocument doc, String placeholder, String value) {
        boolean found = false;
        for (XWPFParagraph paragraph : doc.getParagraphs()) {
            if (replaceInParagraph(paragraph, placeholder, value)) {
                found = true;
            }
        }
        return found;
    }

    /**
     * 在表格中替换
     */
    private static boolean replaceInTables(XWPFDocument doc, String placeholder, String value) {
        boolean found = false;
        for (XWPFTable table : doc.getTables()) {
            for (XWPFTableRow row : table.getRows()) {
                for (XWPFTableCell cell : row.getTableCells()) {
                    for (XWPFParagraph paragraph : cell.getParagraphs()) {
                        if (replaceInParagraph(paragraph, placeholder, value)) {
                            found = true;
                        }
                    }
                }
            }
        }
        return found;
    }

    /**
     * 智能替换
     */
    private static boolean smartReplaceInDocument(XWPFDocument doc, String placeholder, String value) {
        // 尝试处理带格式的占位符
        String cleanPlaceholder = placeholder
                .replaceAll("[\\[\\]{}]", "")
                .replaceAll("\\s+", "");

        if (cleanPlaceholder.length() > 3) {
            // 在文档中搜索类似的文本
            return searchAndReplaceFuzzy(doc, cleanPlaceholder, value);
        }

        return false;
    }

    /**
     * 在段落中执行替换
     */
    private static boolean replaceInParagraph(XWPFParagraph paragraph, String findText, String replaceText) {
        boolean replaced = false;
        for (XWPFRun run : paragraph.getRuns()) {
            String text = run.getText(0);
            if (text != null && text.contains(findText)) {
                run.setText(text.replace(findText, replaceText), 0);
                replaced = true;
            }
        }
        return replaced;
    }

    /**
     * 模糊搜索和替换
     */
    private static boolean searchAndReplaceFuzzy(XWPFDocument doc, String search, String replace) {
        boolean found = false;

        // 搜索段落
        for (XWPFParagraph paragraph : doc.getParagraphs()) {
            String text = paragraph.getText();
            if (text != null && text.toLowerCase().contains(search.toLowerCase())) {
                // 在runs中查找具体位置
                for (XWPFRun run : paragraph.getRuns()) {
                    String runText = run.getText(0);
                    if (runText != null && runText.toLowerCase().contains(search.toLowerCase())) {
                        run.setText(runText.replaceAll("(?i)" + search, replace), 0);
                        found = true;
                    }
                }
            }
        }

        return found;
    }

    /**
     * 使用Map处理定价成本核定表
     */
    private static void processCostTableWithMaps(XWPFDocument document,
                                                 List<String> years,
                                                 List<Map<String, Object>> costItems) {
        System.out.println("开始处理定价成本核定表...");

        // 找到所有表格
        List<XWPFTable> tables = document.getTables();
        if (tables.isEmpty()) {
            System.out.println("未找到表格，创建新表格");
            createNewCostTable(document, years, costItems);
            return;
        }

        // 假设最后一个表格是定价成本核定表
        XWPFTable costTable = tables.get(tables.size() - 1);
        System.out.println("找到表格，当前行数: " + costTable.getRows().size());

        //CompleteTableStyleFixer.fixTableComplete(costTable,years,costItems);
        // 重建表格
        rebuildCostTableWithMaps(costTable, years, costItems);
        TableWidthEnforcer.enforceTableWidth(costTable,100);
    }

    /**
     * 使用Map重建成本核定表
     */
    private static void rebuildCostTableWithMaps(XWPFTable table,
                                                 List<String> years,
                                                 List<Map<String, Object>> costItems) {
        try {
            // 1. 找到表头行
            int headerRowIndex = findCostTableHeaderRow(table);
            System.out.println("表头行索引: " + headerRowIndex);

            // 2. 清空数据区域
            clearCostTableData(table, headerRowIndex);

            // 3. 重建表头（如果需要）
            rebuildTableHeader(table, years, headerRowIndex);

            // 4. 添加数据行
            addCostTableDataRows(table, years, costItems, headerRowIndex);

            // 5. 添加说明行
            //addCostTableFooter(table);
            applyTableBorders(table);
            System.out.println("表格处理完成，最终行数: " + table.getRows().size());
            System.out.println("表格宽度："+table.getWidth());
        } catch (Exception e) {
            System.err.println("表格处理失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 找到成本表表头行
     */
    private static int findCostTableHeaderRow(XWPFTable table) {
        for (int i = 0; i < table.getRows().size(); i++) {
            XWPFTableRow row = table.getRows().get(i);
            String rowText = getRowText(row);
            if (rowText != null &&
                    (rowText.contains("成本项目") || rowText.contains("定价成本"))) {
                return i;
            }
        }
        return 0; // 默认第一行
    }

    /**
     * 清空表格数据区域
     */
    private static void clearCostTableData(XWPFTable table, int headerRowIndex) {
        // 保留表头行，移除后面的行
        for (int i = table.getRows().size() - 1; i > headerRowIndex; i--) {
            table.removeRow(i);
        }
        System.out.println("清理数据区域完成");
    }

    /**
     * 重建表头
     */
    private static void rebuildTableHeader(XWPFTable table,
                                           List<String> years,
                                           int headerRowIndex) {
        XWPFTableRow headerRow;

        if (headerRowIndex < table.getRows().size()) {
            headerRow = table.getRows().get(headerRowIndex);
        } else {
            headerRow = table.createRow();
        }

        // 清空现有单元格
        for (XWPFTableCell cell : headerRow.getTableCells()) {
            clearCellContent(cell);
        }

        // 确保有足够的单元格
        int neededCells = 2 + years.size(); // 成本项目 + 行次 + 各年份
        while (headerRow.getTableCells().size() < neededCells) {
            headerRow.addNewTableCell();
        }

        // 设置表头内容
        List<XWPFTableCell> cells = headerRow.getTableCells();

        // 成本项目列
        setCellText(cells.get(0), "成本项目");

        // 行次列
        setCellText(cells.get(1), "行次");

        // 各年份列
        for (int i = 0; i < years.size(); i++) {
            setCellText(cells.get(2 + i), years.get(i) + "年度");

        }

        System.out.println("表头重建完成，列数: " + cells.size());
    }

    /**
     * 添加数据行
     */
    private static void addCostTableDataRows(XWPFTable table,
                                             List<String> years,
                                             List<Map<String, Object>> costItems,
                                             int startRowIndex) {
        System.out.println("添加 " + costItems.size() + " 行数据");

        for (int i = 0; i < costItems.size(); i++) {
            Map<String, Object> item = costItems.get(i);

            // 创建新行
            XWPFTableRow dataRow = table.createRow();

            // 确保有足够的单元格
            int neededCells = 2 + years.size();
            while (dataRow.getTableCells().size() < neededCells) {
                dataRow.addNewTableCell();
            }

            List<XWPFTableCell> cells = dataRow.getTableCells();

            // 设置成本项目
            String costItemName = (String) item.get("costItemName");
            setCellText(cells.get(0), costItemName != null ? costItemName : "");
            String serialNumber = (String)item.get("serialNumber");
            // 设置行次
            setCellText(cells.get(1), serialNumber != null ? serialNumber : "");

            // 设置各年份数据
            for (int j = 0; j < years.size(); j++) {
                String year = years.get(j);
                Map<String, String> yearValues = (Map<String, String>) item.get("yearValues");
                String value = yearValues != null ? yearValues.get(year) : "";
                setCellText(cells.get(2 + j), value != null ? value : "0");
            }
        }
    }

    /**
     * 添加表格说明
     */
    private static void addCostTableFooter(XWPFTable table) {
        XWPFTableRow footerRow = table.createRow();

        // 合并单元格显示说明
        XWPFTableCell footerCell = footerRow.addNewTableCell();

        try {
            // 获取第一行的列数
            int colCount = table.getRow(0).getTableCells().size();
            footerCell.getCTTc().addNewTcPr().addNewGridSpan()
                    .setVal(BigInteger.valueOf(colCount));
        } catch (Exception e) {
            System.err.println("合并单元格失败，但不影响使用: " + e.getMessage());
        }

        // 设置说明文本
        XWPFParagraph paragraph = footerCell.addParagraph();
        XWPFRun run = paragraph.createRun();
        run.setText("说明：本表应根据行业会计制度及监审项目不同制表，对成本科目及计算方法做相应调整。");
    }

    /**
     * 创建新的成本表（如果没有找到表格）
     */
    private static void createNewCostTable(XWPFDocument document,
                                           List<String> years,
                                           List<Map<String, Object>> costItems) {
        XWPFTable newTable = document.createTable();

        // 创建表头行
        XWPFTableRow headerRow = newTable.getRow(0);

        // 添加表头列
        XWPFTableCell cell1 = headerRow.getCell(0);
        setCellText(cell1, "成本项目");

        XWPFTableCell cell2 = headerRow.addNewTableCell();
        setCellText(cell2, "行次");

        for (String year : years) {
            XWPFTableCell yearCell = headerRow.addNewTableCell();
            setCellText(yearCell, year + "年度");
        }

        // 添加数据行
        addCostTableDataRows(newTable, years, costItems, 1);

        // 添加说明行
        //addCostTableFooter(newTable);

        System.out.println("新表格创建完成");
    }

    // ========== 工具方法 ==========

    /**
     * 设置单元格文本
     */
    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();
        paragraph.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun run = paragraph.createRun();
        //cell.setWidth("2000");
        run.setText(text != null ? text : "");
    }

    /**
     * 清空单元格内容
     */
    private static void clearCellContent(XWPFTableCell cell) {
        for (int i = cell.getParagraphs().size() - 1; i >= 0; i--) {
            cell.removeParagraph(i);
        }
    }

    /**
     * 获取行文本
     */
    private static String getRowText(XWPFTableRow row) {
        StringBuilder sb = new StringBuilder();
        for (XWPFTableCell cell : row.getTableCells()) {
            sb.append(getCellText(cell));
        }
        return sb.toString();
    }

    /**
     * 获取单元格文本
     */
    private static String getCellText(XWPFTableCell cell) {
        StringBuilder sb = new StringBuilder();
        for (XWPFParagraph paragraph : cell.getParagraphs()) {
            String text = paragraph.getText();
            if (text != null) {
                sb.append(text);
            }
        }
        return sb.toString();
    }













    /**
     * 应用表格边框
     */
    private static void applyTableBorders(XWPFTable table) {
        try {
            //table.setWidth(1000);
            CTTblPr tblPr = table.getCTTbl().getTblPr();
            if (tblPr == null) {
                tblPr = table.getCTTbl().addNewTblPr();
            }

            // 创建或获取边框设置
            CTTblBorders borders = tblPr.getTblBorders();
            if (borders == null) {
                borders = tblPr.addNewTblBorders();
            }

            // 设置外部边框（粗）
            setBorder(borders.addNewTop(), "single", 8, "000000");
            setBorder(borders.addNewLeft(), "single", 8, "000000");
            setBorder(borders.addNewBottom(), "single", 8, "000000");
            setBorder(borders.addNewRight(), "single", 8, "000000");

            // 设置内部边框（细）
            setBorder(borders.addNewInsideH(), "single", 4, "000000");
            setBorder(borders.addNewInsideV(), "single", 4, "000000");

            System.out.println("✅ 表格边框设置完成");

        } catch (Exception e) {
            System.err.println("设置表格边框失败: " + e.getMessage());
        }
    }

    /**
     * 设置边框样式
     */
    private static void setBorder(CTBorder border, String style, int size, String color) {
        border.setVal(STBorder.Enum.forString(style));
        border.setSz(BigInteger.valueOf(size));
        border.setColor(color);
    }




}
