package com.hotent.util.wordexcelutils;/**
 * @program: cbjs-mvue-master
 * @description:
 * @author: zhao yue yue
 * @create: 2025-11-27 15:34
 */

import com.hotent.base.util.StringUtil;
import lombok.Data;
import lombok.Getter;
import org.apache.poi.xwpf.usermodel.*;
import java.util.*;
import java.io.*;

/**
 *@author: zhao yue yue
 *@create: 2025-11-27 15:34
 */
public class CompleteTemplateProcessor {

    /**
     * 完整处理模板：替换占位符 + 填充表格数据
     */
    public static void processTemplateComplete(XWPFDocument document,
                                               String organizationName,
                                               List<TableRowData> rowDataList,
                                               String generateDate) {

        // 1. 计算汇总信息
        int totalPages = calculateTotalPages(rowDataList);
        int totalDocuments = rowDataList.size();

        System.out.println("开始处理模板...");
        System.out.println("单位名称: " + organizationName);
        System.out.println("数据行数: " + totalDocuments);
        System.out.println("总页数: " + totalPages);
        System.out.println("生成日期: " + generateDate);

        // 2. 替换文档中的占位符
        //replaceDocumentPlaceholders(document, organizationName, totalDocuments, totalPages, generateDate);
        // 替换映射
        Map<String, String> replacements = new HashMap<>();
        replacements.put("{价格主管部门或成本监审机构}", organizationName);
        replacements.put("{材料件数}", String.valueOf(totalDocuments));
        replacements.put("{材料页数}", String.valueOf(totalPages));
        replacements.put("{登记表生成日期}", generateDate);
        replacements.put("{序号}", "1");
        replacements.put("{资料名称}", rowDataList.get(0).getDocumentName());
        replacements.put("{页数}", String.valueOf(rowDataList.get(0).getPageCount()));
        replacements.put("{备注}", rowDataList.get(0).getRemark());
        SmartTemplateWriter.writeToTemplate(document,replacements);

        // 3. 处理表格数据
        processTableData(document, rowDataList);

        System.out.println("模板处理完成！");
    }

    /**
     * 计算总页数
     */
    private static int calculateTotalPages(List<TableRowData> rowDataList) {
        return rowDataList.stream().mapToInt(TableRowData::getPageCount).sum();
    }

    /**
     * 替换文档中的占位符
     */
    private static void replaceDocumentPlaceholders(XWPFDocument document,
                                                    String organizationName,
                                                    int totalDocuments,
                                                    int totalPages,
                                                    String generateDate) {

        // 替换映射
        Map<String, String> replacements = new HashMap<>();
        replacements.put("{价格主管部门或成本监审机构}", organizationName);
        replacements.put("{材料件数}", String.valueOf(totalDocuments));
        replacements.put("{材料页数}", String.valueOf(totalPages));
        replacements.put("{登记表生成日期}", generateDate);

        // 在文档中查找并替换
        for (Map.Entry<String, String> entry : replacements.entrySet()) {
            boolean found = replaceTextInDocument(document, entry.getKey(), entry.getValue());
            if (!found) {
                System.out.println("警告: 未找到占位符 " + entry.getKey());
            } else {
                System.out.println("成功替换: " + entry.getKey() + " → " + entry.getValue());
            }
        }
    }

    /**
     * 处理表格数据
     */
    private static void processTableData(XWPFDocument document, List<TableRowData> rowDataList) {
        List<XWPFTable> tables = document.getTables();
        if (tables.isEmpty()) {
            System.err.println("错误: 未找到表格");
            return;
        }

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

        // 找到模板行（包含占位符的行）
        //int templateRowIndex = findTemplateRow(table);
       /* if (templateRowIndex == -1) {
            System.err.println("错误: 未找到包含占位符的模板行");
            return;
        }*/

        System.out.println("模板行索引: " + 1);

        // 处理表格数据
        processTableRows(table, 1, rowDataList);
    }

    /**
     * 找到包含占位符的模板行
     */
    private static int findTemplateRow(XWPFTable table) {
        for (int i = 0; i < table.getRows().size(); i++) {
            XWPFTableRow row = table.getRows().get(i);
            if (containsTablePlaceholders(row)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 检查行是否包含表格占位符
     */
    private static boolean containsTablePlaceholders(XWPFTableRow row) {
        String[] placeholders = {"{序号}", "{资料名称}", "{页数}", "{备注}"};
        String rowText = getRowText(row);

        if (rowText == null) return false;

        for (String placeholder : placeholders) {
            if (rowText.contains(placeholder)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 处理表格行数据
     */
    private static void processTableRows(XWPFTable table, int templateRowIndex, List<TableRowData> rowDataList) {
        XWPFTableRow templateRow = table.getRows().get(templateRowIndex);

        // 1. 首先替换模板行（第一行数据）
       /* if (rowDataList.size() > 0) {
            replaceTemplateRow(templateRow, rowDataList.get(0), 1);
            System.out.println("替换模板行完成");
        }*/

        // 2. 添加额外的数据行
        for (int i = 1; i < rowDataList.size(); i++) {
            addDataRow(table, templateRow, rowDataList.get(i), i + 1, templateRowIndex + i);
            System.out.println("添加数据行: " + (i + 1));
        }

        // 3. 清理多余的空行（保留汇总行）
        cleanupEmptyRows(table, templateRowIndex + rowDataList.size());

        System.out.println("表格处理完成，最终行数: " + table.getRows().size());
    }

    /**
     * 替换模板行
     */
    private static void replaceTemplateRow(XWPFTableRow row, TableRowData data, int sequence) {
        List<XWPFTableCell> cells = row.getTableCells();
        if (cells.size() < 4) {
            System.err.println("错误: 表格列数不足");
            return;
        }

        // 替换占位符
        //replaceInCell(cells.get(0), "[{序号}]", String.valueOf(sequence));
       // replaceInCell(cells.get(1), "[{资料名称}]", data.getDocumentName());
       // replaceInCell(cells.get(2), "[{页数}]", data.getPageCount() > 0 ? String.valueOf(data.getPageCount()) : "");
       // replaceInCell(cells.get(3), "[{备注}]", data.getRemark() != null ? data.getRemark() : "");
    }

    /**
     * 添加数据行
     */
    private static void addDataRow(XWPFTable table, XWPFTableRow templateRow, TableRowData data, int sequence, int insertIndex) {
        // 创建新行
        XWPFTableRow newRow = table.insertNewTableRow(insertIndex);

        // 复制模板行的单元格结构
        for (int i = 0; i < templateRow.getTableCells().size(); i++) {
            XWPFTableCell newCell = newRow.addNewTableCell();
            // 复制单元格样式（简化）
            copyCellStyle(templateRow.getTableCells().get(i), newCell);
        }

        // 填充数据
        List<XWPFTableCell> cells = newRow.getTableCells();
        setCellText(cells.get(0), String.valueOf(sequence));
        setCellText(cells.get(1), data.getDocumentName());
        setCellText(cells.get(2), data.getPageCount() > 0 ? String.valueOf(data.getPageCount()) : "");
        setCellText(cells.get(3), data.getRemark() != null ? data.getRemark() : "");
    }

    /**
     * 清理多余的空行
     */
    private static void cleanupEmptyRows(XWPFTable table, int startIndex) {
        // 找到汇总行
        int summaryRowIndex = findSummaryRow(table);
        if (summaryRowIndex == -1) return;

        // 清理汇总行之前的空行
        for (int i = summaryRowIndex - 1; i >= startIndex; i--) {
            if (i < table.getRows().size() && isRowEmpty(table.getRows().get(i))) {
                table.removeRow(i);
                System.out.println("清理空行: " + i);
            }
        }
    }

    /**
     * 找到汇总行
     */
    private static int findSummaryRow(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("以上材料共")) {
                return i;
            }
        }
        return -1;
    }

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

    /**
     * 替换文档中的文本
     */
    private static boolean replaceTextInDocument(XWPFDocument document, String findText, String replaceText) {
        boolean found = false;

        // 在段落中查找
        for (XWPFParagraph paragraph : document.getParagraphs()) {
            if (replaceInParagraph(paragraph, findText, replaceText)) {
                found = true;
            }
        }

        // 在表格中查找
        for (XWPFTable table : document.getTables()) {
            for (XWPFTableRow row : table.getRows()) {
                for (XWPFTableCell cell : row.getTableCells()) {
                    for (XWPFParagraph paragraph : cell.getParagraphs()) {
                        if (replaceInParagraph(paragraph, findText, replaceText)) {
                            found = true;
                        }
                    }
                }
            }
        }

        return found;
    }

    private static boolean replaceInParagraph(XWPFParagraph paragraph, String findText, String replaceText) {
        boolean found = false;
        for (XWPFRun run : paragraph.getRuns()) {
            String text = run.getText(0);
            if (text != null && text.contains(findText)) {
                run.setText(text.replace(findText, replaceText), 0);
                found = true;
            }
        }
        return found;
    }

    /**
     * 替换单元格中的文本
     */
    private static void replaceInCell(XWPFTableCell cell, String findText, String replaceText) {
        for (XWPFParagraph paragraph : cell.getParagraphs()) {
            for (XWPFRun run : paragraph.getRuns()) {
                String text = run.getText(0);
                if (text != null && text.contains(findText)) {
                    run.setText(text.replace(findText, replaceText), 0);
                }
            }
        }
    }

    /**
     * 设置单元格文本
     */
    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);
    }

    /**
     * 复制单元格样式
     */
    private static void copyCellStyle(XWPFTableCell source, XWPFTableCell target) {
        try {
            target.setColor(source.getColor());
            if (StringUtil.isNotEmpty(String.valueOf(source.getWidth()) )) {
                target.setWidth(String.valueOf(source.getWidth()));
            }
        } catch (Exception e) {
            // 忽略样式复制错误
        }
    }

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

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

    /**
     * 检查行是否为空
     */
    private static boolean isRowEmpty(XWPFTableRow row) {
        for (XWPFTableCell cell : row.getTableCells()) {
            String text = getCellText(cell);
            if (text != null && !text.trim().isEmpty()) {
                return false;
            }
        }
        return true;
    }

    /**
     * 表格行数据类
     */
    @Getter
    @Data
    public static class TableRowData {
        private String documentName;
        private int pageCount;
        private String remark;

        public TableRowData() {
            this.documentName = documentName;
            this.pageCount = pageCount;
            this.remark = remark;
        }

    }
}
