"""
PDF 全文提取实现 - 简化版

仅使用 PyMuPDF 本地提取，不进行 OCR。
支持页眉页脚过滤。
"""

from __future__ import annotations

import io
import re
from typing import Any, Dict, List

import fitz  # PyMuPDF

from foundation.observability.cachefiles.cache_manager import cache, CacheBaseDir

from ..interfaces import DocumentSource, FullTextExtractor


class PdfFullTextExtractor(FullTextExtractor):
    """
    按页提取 PDF 全文内容（简化版）

    特点：
    - 仅本地提取，不使用 OCR
    - 自动过滤页眉页脚
    - 裁剪顶部/底部区域
    """

    # 页眉页脚过滤关键词
    HEADER_FOOTER_KEYWORDS = [
        "四川路桥建设集团股份有限公司",
        "T梁运输及安装专项施工方案",
    ]

    def __init__(
        self,
        clip_top: float = 60,
        clip_bottom: float = 60,
    ) -> None:
        """
        初始化

        Args:
            clip_top: 顶部裁剪磅数（过滤页眉）
            clip_bottom: 底部裁剪磅数（过滤页脚）
        """
        self.clip_top = clip_top
        self.clip_bottom = clip_bottom

    def extract_full_text(self, source: DocumentSource) -> List[Dict[str, Any]]:
        """提取PDF全文内容"""
        if source.content is not None:
            doc = fitz.open(stream=io.BytesIO(source.content))
            source_file = "bytes_stream"
        elif source.path is not None:
            doc = fitz.open(source.path)
            source_file = str(source.path)
        else:
            raise ValueError("DocumentSource 既没有 path 也没有 content")

        pages: List[Dict[str, Any]] = []
        current_pos = 0

        try:
            for page_num in range(len(doc)):
                page = doc[page_num]

                # 裁剪页眉页脚区域
                rect = page.rect
                clip_box = fitz.Rect(0, self.clip_top, rect.width, rect.height - self.clip_bottom)

                # 提取文本
                text = page.get_text("text", clip=clip_box)

                # 过滤页眉页脚
                text = self._filter_header_footer(text)

                pages.append({
                    "page_num": page_num + 1,
                    "text": text,
                    "start_pos": current_pos,
                    "end_pos": current_pos + len(text),
                    "source_file": source_file,
                })
                current_pos += len(text)

        finally:
            doc.close()

        # 保存到缓存
        cache.save(
            data=pages,
            subdir="document_temp",
            filename="原始pdf结果.json",
            base_cache_dir=CacheBaseDir.CONSTRUCTION_REVIEW
        )

        return pages

    def _clean_extracted_text(self, text: str) -> str:
        """
        清理提取的文本，移除 PyMuPDF 添加的不必要空格

        问题：PyMuPDF 在提取 PDF 文本时，有时会在中文字符和数字/标点之间
        添加不必要的空格（如 "(国务院令第279 号)" 变成 "(国务院令第279 号)"）

        处理规则：
        1. 移除中文和数字之间的空格：第279 号 -> 第279号
        2. 移除中文和中文标点之间的空格
        3. 保留英文单词之间的空格
        4. 保留换行符

        Args:
            text: 原始提取的文本

        Returns:
            清理后的文本
        """
        import re

        if not text:
            return text

        # 定义中文字符范围（包括中文标点）
        chinese_char = r'[\u4e00-\u9fff]'
        chinese_punctuation = r'[\u3000-\u303f\uff00-\uffef]'
        digit = r'[0-9]'
        ascii_letter = r'[a-zA-Z]'

        # 规则1: 中文数字 + 空格 + 数字中文 -> 移除空格
        # 例：第279 号 -> 第279号，令 第 -> 令第
        text = re.sub(r'(' + chinese_char + r') +(' + digit + r')', r'\1\2', text)
        text = re.sub(r'(' + digit + r') +(' + chinese_char + r')', r'\1\2', text)

        # 规则2: 中文 + 空格 + 中文标点 -> 移除空格
        text = re.sub(r'(' + chinese_char + r') +(' + chinese_punctuation + r')', r'\1\2', text)
        text = re.sub(r'(' + chinese_punctuation + r') +(' + chinese_char + r')', r'\1\2', text)

        # 规则3: 连续中文之间的空格 -> 移除
        text = re.sub(r'(' + chinese_char + r') +(' + chinese_char + r')', r'\1\2', text)

        # 规则4: 括号内的数字空格处理
        # 例：(279 号) -> (279号)，[123 号] -> [123号]
        text = re.sub(r'\((' + digit + r'+) +(' + chinese_char + r'+)\)', r'(\1\2)', text)
        text = re.sub(r'（(' + digit + r'+) +(' + chinese_char + r'+)）', r'（\1\2）', text)
        text = re.sub(r'\[(' + digit + r'+) +(' + chinese_char + r'+)\]', r'[\1\2]', text)

        # 规则5: 处理编号格式中的空格，如 "GB 51-2001" 保持，但 "GB51 -2001" 修复
        # 保留标准编号格式中的空格，但修复不合理的空格

        # 规则6: 循环清理中文之间的多个连续空格
        # 对于"建 设 工 程"这种情况，需要多次应用正则
        max_iterations = 10  # 防止无限循环
        for _ in range(max_iterations):
            prev_text = text
            text = re.sub(r'(' + chinese_char + r') +(' + chinese_char + r')', r'\1\2', text)
            if text == prev_text:
                break

        return text

    def _filter_header_footer(self, text: str) -> str:
        """
        过滤页眉页脚

        规则：
        1. 包含特定关键词的行
        2. 纯数字（页码）
        3. 常见页码格式
        """
        lines = text.split("\n")
        filtered_lines: List[str] = []

        for line in lines:
            stripped = line.strip()

            if not stripped:
                continue

            # 过滤特定关键词
            skip = False
            for keyword in self.HEADER_FOOTER_KEYWORDS:
                if keyword in stripped:
                    skip = True
                    break
            if skip:
                continue

            # 过滤纯数字页码
            if stripped.isdigit():
                continue

            # 过滤常见页码格式
            if re.match(r'^[-\s]*\d+[-\s]*$', stripped):
                continue

            filtered_lines.append(line)

        return "\n".join(filtered_lines)
