from __future__ import annotations

from app.core.rag.indexing.docs.frontmatter_view import DocsFrontmatterView
from app.core.rag.indexing.docs.models import RelationEdge


class DocsRelationExtractor:
    def extract(self, frontmatter: dict, *, source_id: str) -> list[RelationEdge]:
        edges: list[RelationEdge] = []
        view = DocsFrontmatterView(frontmatter)
        if view.parent:
            edges.append(
                RelationEdge(
                    source_id=source_id,
                    relation_type="parent",
                    target_id=view.parent,
                    anchor="frontmatter.parent",
                )
            )
        for child in view.children:
            edges.append(
                RelationEdge(
                    source_id=source_id,
                    relation_type="child",
                    target_id=child,
                    anchor="frontmatter.children",
                )
            )
        for related_doc in view.related_docs:
            edges.append(
                RelationEdge(
                    source_id=source_id,
                    relation_type="related_doc",
                    target_id=related_doc,
                    anchor="frontmatter.related_docs",
                )
            )
        for entity in view.entities:
            edges.append(
                RelationEdge(
                    source_id=source_id,
                    relation_type="mentions_entity",
                    target_id=entity,
                    anchor="frontmatter.entities",
                )
            )
        links = view.links
        if isinstance(links, dict):
            for relation_type, values in links.items():
                for target in self._targets(values):
                    edges.append(
                        RelationEdge(
                            source_id=source_id,
                            relation_type=str(relation_type or "").strip(),
                            target_id=target,
                            anchor=f"frontmatter.links.{relation_type}",
                        )
                    )
            return edges
        for item in links if isinstance(links, list) else []:
            if not isinstance(item, dict):
                continue
            relation_type = str(item.get("type") or "").strip()
            target = str(item.get("target") or "").strip()
            if relation_type and target:
                edges.append(
                    RelationEdge(
                        source_id=source_id,
                        relation_type=relation_type,
                        target_id=target,
                        anchor="frontmatter.links",
                    )
                )
        return edges

    def _targets(self, value) -> list[str]:
        if not isinstance(value, list):
            return []
        result: list[str] = []
        for item in value:
            if isinstance(item, dict):
                target = str(item.get("target") or item.get("id") or "").strip()
            else:
                target = str(item or "").strip()
            if target:
                result.append(target)
        return result
