"""FastAPI service exposing the travel-insurance agent.

    uvicorn app.server:app --host 0.0.0.0 --port 8000

The LLM is called lazily, so the API + RAG + cache layer boots even if the vLLM server isn't up
yet (useful for testing retrieval/cache in isolation).
"""
from __future__ import annotations

import os
import sys
from pathlib import Path

# Allow `uvicorn app.server:app` to find the src/ package without installing.
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))

from fastapi import FastAPI, File, HTTPException, UploadFile  # noqa: E402
from fastapi.responses import FileResponse  # noqa: E402
from pydantic import BaseModel, Field  # noqa: E402

from agent.pipeline import Agent  # noqa: E402
from agent.settings import load_config  # noqa: E402

app = FastAPI(title="Travel-Insurance Agent", version="0.1.0")

STATIC_DIR = Path(__file__).resolve().parent / "static"

_config_path = os.environ.get("AGENT_CONFIG")  # optional override
_cfg = load_config(_config_path)
_agent = Agent(_cfg, lazy_llm=True)
_transcriber = None  # lazy local STT (faster-whisper)


def _get_transcriber():
    global _transcriber
    if _transcriber is None:
        from agent.stt import Transcriber

        _transcriber = Transcriber(_cfg)
    return _transcriber


class ChatRequest(BaseModel):
    query: str = Field(..., min_length=1, description="The user's travel-insurance question")


class ChatResponse(BaseModel):
    answer: str
    citations: list[str]
    cached: bool
    grounded: bool
    guardrail_reason: str = ""
    similarity: float | None = None
    prompt_tokens: int = 0
    completion_tokens: int = 0
    total_tokens: int = 0
    route: str = "llm"


@app.get("/")
def index() -> FileResponse:
    """Serve the voice web UI (must be loaded via http://localhost so the mic works)."""
    return FileResponse(STATIC_DIR / "index.html")


@app.get("/health")
def health() -> dict:
    return {"status": "ok"}


@app.post("/chat", response_model=ChatResponse)
def chat(req: ChatRequest) -> ChatResponse:
    resp = _agent.answer(req.query)
    return ChatResponse(**_agent.to_dict(resp))


@app.post("/transcribe")
async def transcribe(audio: UploadFile = File(...)) -> dict:
    """Transcribe uploaded mic audio locally (faster-whisper). Audio never leaves this machine."""
    try:
        t = _get_transcriber()
    except ImportError:
        raise HTTPException(503, "Local STT not installed. Run: pip install -e '.[voice]'")
    data = await audio.read()
    try:
        text = t.transcribe(data)
    except Exception as e:  # noqa: BLE001
        raise HTTPException(500, f"transcription failed: {e}")
    return {"text": text}
