"""
LlamaIndex adapter — maps ChunkRecord → llama_index TextNode.
No hard dependency: llama_index is imported inside the class.
"""

from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    pass


class ExtractorReader:
    """
    LlamaIndex BaseReader compatible class.

    Usage:
        from extractor.integrations.llamaindex import ExtractorReader
        nodes = ExtractorReader().load_data("paper.pdf")
    """

    def __init__(self, **default_kwargs):
        self.default_kwargs = default_kwargs

    def load_data(self, file: Path | str, **kwargs) -> list:
        try:
            from llama_index.core.schema import TextNode
        except ImportError as e:
            raise ImportError(
                "llama-index-core not installed. Run: pip install llama-index-core"
            ) from e

        from extractor import extract

        merged_kwargs = dict(self.default_kwargs)
        merged_kwargs.update(kwargs)
        merged_kwargs.setdefault("mode", "chunks")

        nodes = []
        for chunk in extract(Path(file), **merged_kwargs):
            from extractor.schema import ChunkRecord

            if not isinstance(chunk, ChunkRecord):
                raise TypeError(
                    f"ExtractorReader requires mode='chunks' or mode='dual-chunks', "
                    f"got {type(chunk).__name__}. Set mode='chunks' in extract_kwargs."
                )
            entities = getattr(chunk, "entities", None) or []
            entity_types = (
                chunk.chunk_metadata.entity_types
                if chunk.chunk_metadata and chunk.chunk_metadata.entity_types
                else []
            )
            nodes.append(
                TextNode(
                    text=chunk.text,
                    id_=chunk.id,
                    metadata={
                        "file_name": chunk.source_filename,
                        "page_label": str(chunk.page or ""),
                        "section_path": " > ".join(chunk.section_path or []),
                        "element_type": chunk.element_type,
                        "source_sha256": chunk.source_sha256,
                        "token_count": chunk.token_count,
                        # Entity metadata for retrieval-time filtering
                        "entity_types": entity_types,
                        "entities": [e.model_dump(exclude_none=True) for e in entities],
                    },
                    # Exclude entity JSON from LLM synthesis prompt to avoid noise
                    # (~600 bytes per chunk), while keeping it for metadata filtering
                    excluded_llm_metadata_keys=["entities", "source_sha256"],
                    excluded_embed_metadata_keys=["entities", "source_sha256"],
                )
            )
        return nodes
