"""PrecedentSearch — higher-level API for finding relevant past decisions."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Any

from koan.graph.queries import find_precedents, get_run_trace

if TYPE_CHECKING:
    from koan.graph.client import GraphClient, GraphRecord


@dataclass
class PrecedentResult:
    """A single precedent decision with its context."""

    decision_id: str
    description: str
    reasoning: str
    confidence: float
    timestamp: str
    outcome_status: str | None = None
    evaluation_score: float | None = None
    metadata: dict[str, Any] = field(default_factory=dict)


class PrecedentSearch:
    """High-level API for finding and ranking past decisions.

    Combines graph-based precedent queries with optional filtering
    and ranking. Can be extended with vector similarity for hybrid
    retrieval.

    Usage::

        search = PrecedentSearch(graph_client)

        # Find precedents for a specific entity and decision type
        results = await search.find(
            entity_id="acct-123",
            decision_type="exception",
            limit=5,
        )

        for r in results:
            print(r.description, r.outcome_status)
    """

    def __init__(self, client: GraphClient) -> None:
        self._client = client

    async def find(
        self,
        *,
        entity_id: str,
        decision_type: str,
        before: str | None = None,
        limit: int = 5,
        min_confidence: float = 0.0,
    ) -> list[PrecedentResult]:
        """Find precedent decisions for an entity.

        Args:
            entity_id: Entity to search precedents for.
            decision_type: Filter to this decision type.
            before: ISO timestamp upper bound.
            limit: Max results.
            min_confidence: Filter out decisions below this confidence.

        Returns:
            List of PrecedentResult, ordered by timestamp descending.
        """
        records = await find_precedents(
            self._client,
            entity_id=entity_id,
            decision_type=decision_type,
            before=before,
            limit=limit,
        )

        results: list[PrecedentResult] = []
        for r in records:
            confidence = r.data.get("confidence", 0.0) or 0.0
            if confidence < min_confidence:
                continue

            results.append(
                PrecedentResult(
                    decision_id=r.data.get("decision_id", ""),
                    description=r.data.get("description", ""),
                    reasoning=r.data.get("reasoning", ""),
                    confidence=confidence,
                    timestamp=str(r.data.get("timestamp", "")),
                    outcome_status=r.data.get("outcome_status"),
                    evaluation_score=r.data.get("evaluation_score"),
                )
            )

        return results

    async def get_trace(self, run_id: str) -> list[GraphRecord]:
        """Retrieve the full decision trace for a run.

        Convenience wrapper around ``get_run_trace()``.
        """
        return await get_run_trace(self._client, run_id)
