"""
目录模式匹配工具（PDF / Word 通用）

该实现与原 doc_worker 中的 TOCPatternMatcher 逻辑等价，
但独立存在于 file_parse.utils 中，便于被多种 worker 复用。
"""

from __future__ import annotations

import re
from typing import Any, Dict, List

from ..config.provider import default_config_provider


class TOCPatternMatcher:
    """目录模式匹配器。"""

    def __init__(self) -> None:
        self._cfg = default_config_provider

    @staticmethod
    def extract_page_number(page_str: str) -> str:
        """
        从可能带有修饰符号的页码字符串中提取纯数字。
        
        例如：
        - '‐ 1 ‐' -> '1'
        - '19' -> '19'
        - ' 10 ' -> '10'
        - '‐ 19 ‐' -> '19'
        """
        # 使用正则表达式提取第一个连续的数字序列
        match = re.search(r'\d+', page_str)
        if match:
            return match.group(0)
        return page_str.strip()  # 如果没有找到数字，返回清理后的原始字符串

    def has_numbering(self, text: str) -> bool:
        """检查文本是否包含编号格式。"""
        numbering_patterns: List[str] = self._cfg.get("numbering.formats", [])
        for pattern in numbering_patterns:
            if re.match(pattern, text):
                return True
        return False

    def detect_toc_patterns(self, text: str) -> List[Dict[str, Any]]:
        """检测文本中的目录模式，返回 toc_items 列表。"""
        toc_items: List[Dict[str, Any]] = []
        lines = text.split("\n")

        # 预处理：合并可能分行的目录项（保持与原逻辑一致）
        merged_lines: List[str] = []
        i = 0
        while i < len(lines):
            line = lines[i].strip()
            if re.match(r"^第[一二三四五六七八九十\d]+[章节条款]\s*$", line):
                if i + 1 < len(lines):
                    next_line = lines[i + 1].strip()
                    # 支持带修饰符号的页码匹配
                    if re.search(r"[.·]{2,}.*?\d+.*?\s*$", next_line):
                        merged_line = line + next_line
                        merged_lines.append(merged_line)
                        i += 2
                        continue
            merged_lines.append(line)
            i += 1

        patterns: List[str] = self._cfg.get("toc_detection.patterns", [])
        min_length: int = int(self._cfg.get("toc_detection.min_length", 3))
        max_length: int = int(self._cfg.get("toc_detection.max_length", 200))
        noise_patterns: List[str] = self._cfg.get("noise_filters.patterns", [])

        def is_likely_noise(text_val: str) -> bool:
            for pat in noise_patterns:
                if re.search(pat, text_val):
                    return True
            return False

        for line in merged_lines:
            line = line.strip()
            if len(line) < min_length or len(line) > max_length:
                continue
            if line.isdigit():
                continue

            for pattern in patterns:
                match = re.match(pattern, line)
                if not match:
                    continue

                title = match.group(1).strip()
                page_num_raw = match.group(2).strip()
                
                # 从可能带有修饰符号的页码中提取纯数字
                page_num = self.extract_page_number(page_num_raw)

                title_clean = re.sub(r"[.·]{2,}", "", title)
                title_clean = re.sub(r"\s{2,}", " ", title_clean)
                title_clean = title_clean.strip()

                if title_clean and not is_likely_noise(title_clean):
                    toc_items.append(
                        {
                            "original": line,
                            "title": title_clean,
                            "page": page_num,
                            "level": 1,  # 初始层级，后续由层级识别器覆盖
                        }
                    )
                    break

        return toc_items

