"""Base parser interface and RawElement dataclass."""

from __future__ import annotations

from abc import ABC, abstractmethod
from collections.abc import Iterator
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any


@dataclass
class RawElement:
    """
    Intermediate representation emitted by parsers before normalization.
    Parsers yield RawElement; the pipeline normalizes to BaseElement.
    """

    element_type: str
    text: str
    page: int | None = None
    heading_level: int | None = None  # 1-6 for headings, None otherwise
    detection_tier: int = 1  # quality tier for heading detection
    extra: dict[str, Any] = field(default_factory=dict)
    # Sub-object data (passed through to schema models)
    table_data: dict[str, Any] | None = None
    equation_data: dict[str, Any] | None = None
    citation_data: dict[str, Any] | None = None
    reference_data: dict[str, Any] | None = None
    figure_data: dict[str, Any] | None = None
    image_data: dict[str, Any] | None = None
    admonition_data: dict[str, Any] | None = None
    transcript_data: dict[str, Any] | None = None
    list_data: dict[str, Any] | None = None  # list_index, list_depth


@dataclass
class FileRecord:
    """Everything the pipeline knows about the source file."""

    path: Path
    sha256: str
    size_bytes: int
    mime_type: str
    subtype: str | None = None  # e.g. "digital", "scientific", "scanned" for PDFs


class BaseParser(ABC):
    """Abstract base class for all format parsers."""

    # Subclasses declare which (mime_type, subtype) keys they handle
    handles: list[tuple[str, str | None]] = []

    @abstractmethod
    def parse(self, file_record: FileRecord) -> Iterator[RawElement]:
        """
        Parse the source file and yield RawElement records in document order.
        Must be a generator — do not load the full document into memory.
        """
        ...

    @property
    def parser_key(self) -> str:
        """Unique key identifying this parser implementation."""
        return self.__class__.__module__ + "." + self.__class__.__name__
