from __future__ import annotations

from pydantic import Field

from app.models.intent import IntentResult
from app.models.common import StrictModel
from app.models.internal_retrieve import (
    CodeSnippet,
    DocExcerpt,
    HydratedHit,
    RelatedCommit,
)


class SearchOptions(StrictModel):
    top_k: int | None = Field(default=None, ge=1, le=100)
    score_threshold: float | None = Field(default=None, ge=0.0, le=1.0)
    intent_override: str | None = None


class SearchRequest(StrictModel):
    repo_id: str | None = None
    question: str
    snapshot_id: str | None = None
    options: SearchOptions | None = None


class SearchMetadata(StrictModel):
    latency_ms: int | None = None
    retrieval_count: int | None = None
    embedding_model: str | None = None
    top_retrieval_score: float | None = None
    retrieval_fallback_used: bool = False
    retrieval_fallback_pass: str | None = None


class SearchResponse(StrictModel):
    request_id: str
    repo_id: str
    snapshot_id: str
    question: str
    intent: IntentResult
    hits: list[HydratedHit] = Field(default_factory=list)
    code_snippets: list[CodeSnippet] = Field(default_factory=list)
    doc_excerpts: list[DocExcerpt] = Field(default_factory=list)
    related_commits: list[RelatedCommit] = Field(default_factory=list)
    metadata: SearchMetadata = Field(default_factory=SearchMetadata)
    status: str | None = None
    message: str | None = None
