"""Markdown 论文解析器."""

import re
from typing import List

from .models import Reference, Section, ThesisContent, ThesisMetadata


class MarkdownParser:
    """Markdown 论文解析器."""

    def __init__(self) -> None:
        self.metadata = ThesisMetadata()
        self.sections: List[Section] = []
        self.references: List[Reference] = []

    def parse(self, markdown_text: str) -> ThesisContent:
        """解析 Markdown 文本.

        Args:
            markdown_text: Markdown 格式的论文内容

        Returns:
            ThesisContent: 解析后的论文内容结构
        """
        # 清理文本
        text = markdown_text.strip()

        # 提取元数据
        self._extract_metadata(text)

        # 解析章节结构
        self._parse_sections(text)

        # 解析参考文献
        self._parse_references(text)

        return ThesisContent(
            metadata=self.metadata,
            sections=self.sections,
            references=self.references,
        )

    def _extract_metadata(self, text: str) -> None:
        """提取论文元数据."""
        # 提取标题（第一个 # 标题）
        title_match = re.search(r"^#\s+(.+)$", text, re.MULTILINE)
        if title_match:
            self.metadata.title = title_match.group(1).strip()

        # 提取中文摘要
        abstract_cn_match = re.search(
            r"##\s*摘要\s*\n+([\s\S]*?)(?=\n##|\n###|\Z)",
            text,
        )
        if abstract_cn_match:
            self.metadata.abstract_cn = abstract_cn_match.group(1).strip()

        # 提取英文摘要
        abstract_en_match = re.search(
            r"##\s*Abstract\s*\n+([\s\S]*?)(?=\n##|\n###|\Z)",
            text,
            re.IGNORECASE,
        )
        if abstract_en_match:
            self.metadata.abstract_en = abstract_en_match.group(1).strip()

        # 提取中文关键词
        keywords_cn_match = re.search(
            r"##\s*关键词\s*\n+([\s\S]*?)(?=\n##|\n###|\Z)",
            text,
        )
        if keywords_cn_match:
            keywords_text = keywords_cn_match.group(1).strip()
            self.metadata.keywords_cn = [
                k.strip() for k in re.split(r"[,，、]\s*", keywords_text) if k.strip()
            ]

        # 提取英文关键词
        keywords_en_match = re.search(
            r"##\s*Keywords\s*\n+([\s\S]*?)(?=\n##|\n###|\Z)",
            text,
            re.IGNORECASE,
        )
        if keywords_en_match:
            keywords_text = keywords_en_match.group(1).strip()
            self.metadata.keywords_en = [
                k.strip() for k in re.split(r"[,，、]\s*", keywords_text) if k.strip()
            ]

    def _parse_sections(self, text: str) -> None:
        """解析论文章节结构."""
        # 移除元数据部分，只保留正文
        content_text = self._remove_metadata_sections(text)

        # 匹配所有标题
        heading_pattern = r"^(#{1,6})\s+(.+)$"
        matches = list(re.finditer(heading_pattern, content_text, re.MULTILINE))

        if not matches:
            # 没有标题，整个内容作为正文
            self.sections.append(
                Section(
                    title="正文",
                    level=1,
                    content=content_text.strip(),
                )
            )
            return

        # 构建章节树
        section_stack: List[Section] = []

        for i, match in enumerate(matches):
            level = len(match.group(1))
            title = match.group(2).strip()

            # 获取章节内容（到下一个标题之前）
            start_pos = match.end()
            if i + 1 < len(matches):
                end_pos = matches[i + 1].start()
            else:
                end_pos = len(content_text)

            content = content_text[start_pos:end_pos].strip()

            # 创建章节
            section = Section(title=title, level=level, content=content)

            # 确定章节层级关系
            while section_stack and section_stack[-1].level >= level:
                section_stack.pop()

            if section_stack:
                section_stack[-1].subsections.append(section)
            else:
                self.sections.append(section)

            section_stack.append(section)

    def _remove_metadata_sections(self, text: str) -> str:
        """移除元数据部分，返回正文内容."""
        # 找到第一个非元数据章节的位置
        lines = text.split("\n")
        content_start = 0

        for i, line in enumerate(lines):
            # 跳过标题行
            if line.startswith("# ") and i == 0:
                continue
            # 跳过摘要、关键词等元数据章节
            if re.match(r"^##\s*(摘要|Abstract|关键词|Keywords)", line, re.IGNORECASE):
                # 跳过这一节
                j = i + 1
                while j < len(lines) and not lines[j].startswith("##"):
                    j += 1
                content_start = j
                continue

        return "\n".join(lines[content_start:])

    def _parse_references(self, text: str) -> None:
        """解析参考文献."""
        # 匹配参考文献部分
        ref_section_match = re.search(
            r"##\s*参考文献\s*\n+([\s\S]*?)(?=\n##|\Z)",
            text,
        )

        if not ref_section_match:
            return

        ref_text = ref_section_match.group(1)

        # 解析每条参考文献
        # 支持格式：[序号] 内容 或 1. 内容 或 - 内容
        ref_pattern = r"(?:^|\n)\s*(?:\[(\d+)\]|(\d+)[.．])\s*(.+?)(?=\n\s*(?:\[\d+\]|\d+[.．])|\Z)"
        matches = re.findall(ref_pattern, ref_text, re.DOTALL)

        for match in matches:
            index = int(match[0] or match[1])
            content = match[2].strip()
            self.references.append(Reference(index=index, content=content))

        # 如果没有匹配到标准格式，尝试简单分割
        if not self.references:
            lines = [line.strip() for line in ref_text.split("\n") if line.strip()]
            for i, line in enumerate(lines, 1):
                # 移除序号标记
                content = re.sub(r"^\[?\d+\]?[.．\s]*", "", line)
                if content:
                    self.references.append(Reference(index=i, content=content))


def parse_markdown_thesis(markdown_text: str) -> ThesisContent:
    """解析 Markdown 论文.

    Args:
        markdown_text: Markdown 格式的论文内容

    Returns:
        ThesisContent: 解析后的论文内容
    """
    parser = MarkdownParser()
    return parser.parse(markdown_text)
