from __future__ import annotations

from app.core.agent.utils.process_v2.anchor_signals import anchor_signal_types
from app.core.agent.utils.process_v2.models import V2AnchorType, V2RouteResult, V2Subintent
from app.core.rag.contracts.enums import RagLayer
from app.core.rag.retrieval.session_retriever import RetrievalPlan


class DocExplainFindFilesRetrievalPolicy:
    _LAYERS = [RagLayer.DOCS_DOCUMENT_CATALOG, RagLayer.DOCS_ENTITY_CATALOG]

    def supports(self, route: V2RouteResult) -> bool:
        return route.subintent == V2Subintent.FIND_FILES

    def resolve(self, route: V2RouteResult) -> RetrievalPlan:
        return RetrievalPlan(
            profile="file_lookup",
            layers=list(self._LAYERS),
            limit=12,
            filters=self._build_filters(route),
        )

    def _build_filters(self, route: V2RouteResult) -> dict[str, object]:
        filters: dict[str, object] = {"target_doc_hints": list(route.anchors.target_doc_hints)}
        if route.anchors.process_domain:
            filters["metadata.domain"] = route.anchors.process_domain
        if route.anchors.process_subdomain:
            filters["metadata.subdomain"] = route.anchors.process_subdomain
        prefixes = self._path_prefixes(route)
        if prefixes:
            filters["path_prefixes"] = prefixes
        filters["prefer_path_prefixes"] = self._prefer_prefixes(route, prefixes)
        filters["prefer_like_patterns"] = self._like_patterns(route)
        return filters

    def _path_prefixes(self, route: V2RouteResult) -> list[str]:
        hint_prefixes = _prefixes_from_paths(route.anchors.target_doc_hints)
        if hint_prefixes:
            return hint_prefixes
        file_prefixes = [item for item in route.anchors.file_names if str(item).strip().startswith("docs/")]
        derived = _prefixes_from_paths(file_prefixes)
        if derived:
            return derived
        signals = anchor_signal_types(route)
        if V2AnchorType.API_ENDPOINT in signals:
            return ["docs/api/", "docs/"]
        if V2AnchorType.ARCHITECTURE in signals:
            return ["docs/architecture/", "docs/"]
        if V2AnchorType.LOGIC_FLOW in signals:
            return ["docs/logic/", "docs/"]
        if V2AnchorType.DOMAIN_ENTITY in signals:
            return ["docs/domains/", "docs/"]
        return ["docs/"]

    def _prefer_prefixes(self, route: V2RouteResult, prefixes: list[str]) -> list[str]:
        preferred = list(prefixes)
        if route.anchors.process_domain or route.anchors.process_subdomain:
            preferred.extend(["docs/domains/", "docs/logic/"])
        return _unique_terms(preferred or ["docs/"])

    def _like_patterns(self, route: V2RouteResult) -> list[str]:
        if route.anchors.target_doc_hints:
            names = [hint.rsplit("/", 1)[-1] for hint in route.anchors.target_doc_hints if str(hint).strip()]
            return [f"%{name.lower()}%" for name in names]
        terms = list(route.target_terms)
        terms.extend(route.anchors.endpoint_paths)
        terms.extend(route.anchors.file_names)
        terms.extend(route.anchors.entity_names)
        terms.extend(route.anchors.matched_aliases)
        if route.anchors.process_domain:
            terms.append(route.anchors.process_domain)
        if route.anchors.process_subdomain:
            terms.append(route.anchors.process_subdomain)
        return [f"%{term.lower()}%" for term in _unique_terms(terms)]


def _prefixes_from_paths(paths: list[str]) -> list[str]:
    prefixes: list[str] = []
    for path in paths:
        value = str(path).strip().strip("/")
        if "/" not in value:
            continue
        prefix = value.rsplit("/", 1)[0] + "/"
        if prefix:
            prefixes.append(prefix)
    return _unique_terms(prefixes)


def _unique_terms(items: list[str]) -> list[str]:
    seen: set[str] = set()
    unique: list[str] = []
    for raw in items:
        value = str(raw or "").strip()
        if not value or value in seen:
            continue
        seen.add(value)
        unique.append(value)
    return unique

