"""Transcription API endpoints."""

import json
import logging
import os
from typing import Any

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel

logger = logging.getLogger(__name__)

try:
    from python_sidecar.ai.transcriber import AudioTranscriber, Transcript
except ImportError as import_error:
    AudioTranscriber = None  # type: ignore[assignment, misc]
    Transcript = None  # type: ignore[assignment, misc]
    TRANSCRIBER_IMPORT_ERROR: ImportError | None = import_error
else:
    TRANSCRIBER_IMPORT_ERROR = None

router = APIRouter()


class TranscriptionRequest(BaseModel):
    """Request model for transcription."""

    session_dir: str
    language: str | None = None
    model_size: str = "base"


class TranscriptSegmentResponse(BaseModel):
    """Response model for a transcript segment."""

    start_ms: int
    end_ms: int
    text: str
    confidence: float | None = None


class TranscriptResponse(BaseModel):
    """Response model for a full transcript."""

    segments: list[TranscriptSegmentResponse]
    full_text: str
    duration_ms: int
    language: str | None = None


def _transcript_to_dict(transcript: Any) -> dict[str, Any]:
    """Convert a Transcript dataclass to a dictionary."""
    return {
        "segments": [
            {
                "start_ms": seg.start_ms,
                "end_ms": seg.end_ms,
                "text": seg.text,
                "confidence": seg.confidence,
            }
            for seg in transcript.segments
        ],
        "full_text": transcript.full_text,
        "duration_ms": transcript.duration_ms,
        "language": transcript.language,
    }


@router.post("/transcribe", response_model=TranscriptResponse)
async def transcribe_audio(request: TranscriptionRequest) -> TranscriptResponse:
    """Transcribe audio from a session directory.

    Looks for audio.m4a in the session directory, transcribes it,
    and saves the result to transcript.json.
    """
    # Check if transcriber is available
    if AudioTranscriber is None:
        message = "Transcription unavailable: faster-whisper not installed"
        if TRANSCRIBER_IMPORT_ERROR is not None:
            message = f"{message} ({TRANSCRIBER_IMPORT_ERROR})"
        raise HTTPException(status_code=503, detail=message)

    # Validate session directory
    if not os.path.isdir(request.session_dir):
        raise HTTPException(status_code=404, detail="Session directory not found")

    # Find audio file (support multiple formats)
    audio_path: str | None = None
    for filename in ["audio.m4a", "audio.mp3", "audio.wav", "recording.m4a"]:
        candidate = os.path.join(request.session_dir, filename)
        if os.path.exists(candidate):
            audio_path = candidate
            break

    if audio_path is None:
        raise HTTPException(
            status_code=404,
            detail=(
                "No audio file found in session directory "
                "(expected audio.m4a, audio.mp3, audio.wav, or recording.m4a)"
            ),
        )

    try:
        # Create transcriber and transcribe
        transcriber = AudioTranscriber(model_size=request.model_size)
        transcript = transcriber.transcribe(audio_path, language=request.language)

        # Convert to dict for JSON serialization
        result_dict = _transcript_to_dict(transcript)

        # Save transcript to session directory
        transcript_path = os.path.join(request.session_dir, "transcript.json")
        with open(transcript_path, "w") as f:
            json.dump(result_dict, f, indent=2)

        # Return response
        return TranscriptResponse(
            segments=[
                TranscriptSegmentResponse(
                    start_ms=seg.start_ms,
                    end_ms=seg.end_ms,
                    text=seg.text,
                    confidence=seg.confidence,
                )
                for seg in transcript.segments
            ],
            full_text=transcript.full_text,
            duration_ms=transcript.duration_ms,
            language=transcript.language,
        )

    except FileNotFoundError as e:
        logger.warning("Audio file not found in %s", request.session_dir)
        raise HTTPException(status_code=404, detail=str(e)) from e
    except RuntimeError as e:
        logger.exception("Transcription runtime error for %s", request.session_dir)
        raise HTTPException(status_code=500, detail=str(e)) from e
    except Exception as e:
        logger.exception("Transcription failed for %s", request.session_dir)
        raise HTTPException(status_code=500, detail=f"Transcription failed: {e}") from e


@router.get("/health")
async def transcription_health() -> dict[str, str]:
    """Health check for transcription module."""
    if AudioTranscriber is None:
        return {
            "status": "degraded",
            "module": "transcription",
            "reason": "faster-whisper not installed",
        }
    return {"status": "ok", "module": "transcription"}
