"""Сборка candidate rows для general QA summary (метаданные + сиды по hints)."""

from __future__ import annotations

from dataclasses import dataclass

from app.core.agent.utils.process_v2.models import V2RouteResult
from app.core.agent.utils.process_v2.rag_retrieval import DocsMetadataLookupIndex
from app.core.agent.utils.process_v2.rag_retrieval.target_doc_seeding import (
    RagRowIndex,
    merge_row_lists,
    normalize_doc_path,
    normalized_path_set,
    seed_candidates_from_target_hints,
)


@dataclass(slots=True)
class CandidateRowsResult:
    metadata_rows: list[dict]
    rows: list[dict]


class CandidateRowsBuilder:
    def build(self, retrieved_rows: list[dict], route: V2RouteResult) -> CandidateRowsResult:
        metadata_rows = DocsMetadataLookupIndex(retrieved_rows).lookup(route)
        rows = merge_row_lists(retrieved_rows, metadata_rows)
        rows = seed_candidates_from_target_hints(rows, route.anchors.target_doc_hints, RagRowIndex(rows))
        self._print_missing_target_hints(route, rows)
        return CandidateRowsResult(metadata_rows=metadata_rows, rows=rows)

    def _print_missing_target_hints(self, route: V2RouteResult, rows: list[dict]) -> None:
        if not route.anchors.target_doc_hints:
            return
        candidate_paths = normalized_path_set(rows)
        for hint in route.anchors.target_doc_hints:
            if not str(hint or "").strip():
                continue
            normalized = normalize_doc_path(hint)
            if not normalized.startswith("docs/") or "." not in normalized.rsplit("/", 1)[-1]:
                continue
            if normalized not in candidate_paths:
                print("ERROR: target doc missing from candidates:", normalized)
