package top.r3944realms.docchecktoolrefactored.io.reader;

import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import top.r3944realms.docchecktoolrefactored.core.LogicalAddressFileGenerator;
import top.r3944realms.docchecktoolrefactored.util.FileUtil;
import top.r3944realms.docchecktoolrefactored.util.LoggerMarker;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
public class XmlFileReader implements CatalogFileReader {
    // 可配置的元素名列表，按优先级排序
    private static final List<String> RECORD_TAG_CANDIDATES =
            Arrays.asList("row", "record", "data", "item", "档案");

    private static final List<String> ARCHIVE_CODE_TAG_CANDIDATES =
            Arrays.asList("档号", "dangan", "fileNo", "DH");

    private static final List<String> PAGE_COUNT_TAG_CANDIDATES =
            Arrays.asList("页数", "pages", "pageCount", "YS");


    @Override
    public List<LogicalAddressFileGenerator.Record> readCatalogFile(String filePath) throws Exception {
        File file = FileUtil.fileCheckAndGet(filePath, "xml");
        List<LogicalAddressFileGenerator.Record> records = new ArrayList<>();

        try {
            // 创建安全配置的DocumentBuilder
            DocumentBuilder builder = createSecureDocumentBuilder();

            // 解析XML文件
            Document doc = builder.parse(file);
            doc.getDocumentElement().normalize();

            log.debug(LoggerMarker.DEBUG_MARKER, "开始解析XML文件: {}, 根元素: {}",
                    file.getName(), doc.getDocumentElement().getNodeName());
            // 查找记录元素
            NodeList recordNodes = findAllRecordNodes(doc);
            log.debug(LoggerMarker.DEBUG_MARKER, "找到 {} 个潜在记录节点", recordNodes.getLength());

            // 解析每个记录元素
            int validCount = 0;
            int invalidCount = 0;

            for (int i = 0; i < recordNodes.getLength(); i++) {
                Node node = recordNodes.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element recordElement = (Element) node;
                    LogicalAddressFileGenerator.Record record = parseRecordElement(recordElement);

                    if (record != null) {
                        records.add(record);
                        validCount++;
                        log.debug(LoggerMarker.DEBUG_MARKER, "解析到有效记录: {}", record);
                    } else {
                        invalidCount++;
                        log.debug(LoggerMarker.DEBUG_MARKER, "跳过无效记录节点");
                    }
                }
            }
            log.info(LoggerMarker.RELEASE_MARKER, "XML解析完成 - 有效记录: {}, 无效记录: {}", validCount, invalidCount);
        } catch (Exception e) {
            log.error(LoggerMarker.RELEASE_MARKER, "解析XML文件失败: {}", filePath, e);
            throw new Exception("解析XML文件失败: " + filePath, e);
        }
        return records;
    }

    @SuppressWarnings("HttpUrlsUsage")
    private static DocumentBuilder createSecureDocumentBuilder() throws ParserConfigurationException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        // 安全配置防止XXE攻击
        factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
        factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        factory.setXIncludeAware(false);
        factory.setExpandEntityReferences(false);
        return factory.newDocumentBuilder();
    }
    private NodeList findAllRecordNodes(Document doc) {
        // 尝试所有可能的记录标签
        for (String tagName : RECORD_TAG_CANDIDATES) {
            NodeList nodes = doc.getElementsByTagName(tagName);
            if (nodes.getLength() > 0) {
                log.debug(LoggerMarker.DEBUG_MARKER, "使用标签名 '{}' 找到 {} 个记录节点", tagName, nodes.getLength());
                return nodes;
            }
        }
        log.warn(LoggerMarker.DEBUG_MARKER, "未找到任何记录节点，尝试的标签名: {}", RECORD_TAG_CANDIDATES);
        return new EmptyNodeList(); // 返回空节点列表而不是null
    }

    private LogicalAddressFileGenerator.Record parseRecordElement(Element recordElement) {
        String archiveCode = findFirstNonEmptyTextContent(recordElement, ARCHIVE_CODE_TAG_CANDIDATES);
        String pageStr = findFirstNonEmptyTextContent(recordElement, PAGE_COUNT_TAG_CANDIDATES);

        if (archiveCode == null || archiveCode.isEmpty()) {
            log.debug(LoggerMarker.RELEASE_MARKER, "记录缺少档号字段");
            return null;
        }

        try {
            int page = pageStr != null ? Integer.parseInt(pageStr.trim()) : 0;
            if (page > 0) {
                return new LogicalAddressFileGenerator.Record(archiveCode, page);
            } else {
                log.debug(LoggerMarker.RELEASE_MARKER, "无效的页数值: {}", pageStr);
                return null;
            }
        } catch (NumberFormatException e) {
            log.warn(LoggerMarker.RELEASE_MARKER, "页数字段格式错误: {}", pageStr);
            return null;
        }
    }

    private String findFirstNonEmptyTextContent(Element element, List<String> tagNames) {
        for (String tag : tagNames) {
            NodeList nodes = element.getElementsByTagName(tag);
            if (nodes.getLength() > 0) {
                String content = nodes.item(0).getTextContent();
                if (content != null && !content.trim().isEmpty()) {
                    return content.trim();
                }
            }
        }
        return null;
    }

    // 空节点列表实现
    private static class EmptyNodeList implements NodeList {
        @Override public Node item(int index) { return null; }
        @Override public int getLength() { return 0; }
    }


}
