"""Voice-memo transcription.

Async because it makes a network call to a model provider (`react.md`: async
only for AI and SSE routes; the blocking HTTP work is off-loaded to a worker
thread inside the provider).

This route returns TEXT ONLY - it stores nothing. The recording is attached to
the ticket separately at create time, so a failed transcription never costs the
technician their recording or their report.
"""

from __future__ import annotations

from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
from pydantic import BaseModel

from app.services.ai import transcribe as transcription
from app.services.ai.providers.base import TranscriptionError
from app.services.identity import CurrentActor, resolve_actor
from app.services.media import MAX_BYTES

router = APIRouter(prefix="/api/transcribe", tags=["transcription"])


class TranscriptOut(BaseModel):
    text: str
    provider_configured: bool


class TranscriptionStatus(BaseModel):
    """Lets the UI hide the record button when transcription is unavailable,
    rather than offering a control that fails when pressed."""

    configured: bool


@router.get("/status", response_model=TranscriptionStatus)
def status_check() -> TranscriptionStatus:
    return TranscriptionStatus(configured=transcription.is_configured())


@router.post("", response_model=TranscriptOut)
async def transcribe_audio(
    audio: UploadFile = File(...),
    actor: CurrentActor = Depends(resolve_actor),
) -> TranscriptOut:
    content = await audio.read()

    if not content:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail={
                "error_code": "MEDIA_EMPTY",
                "summary": "The recording was empty.",
                "details": "Hold the record button until you have spoken.",
            },
        )
    if len(content) > MAX_BYTES:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail={
                "error_code": "MEDIA_TOO_LARGE",
                "summary": "That recording is too long to transcribe.",
                "details": "Keep voice memos under a couple of minutes.",
            },
        )

    try:
        text = await transcription.transcribe(content, audio.content_type or "")
    except TranscriptionError as exc:
        # 503 for "not set up", 502 for "upstream misbehaved" - the frontend
        # distinguishes a server-config problem from a transient failure.
        code = (
            status.HTTP_503_SERVICE_UNAVAILABLE
            if exc.error_code == "AI_NOT_CONFIGURED"
            else status.HTTP_502_BAD_GATEWAY
        )
        raise HTTPException(
            status_code=code,
            detail={
                "error_code": exc.error_code,
                "summary": exc.summary,
                "details": exc.details,
            },
        ) from None

    return TranscriptOut(text=text, provider_configured=True)
