from typing import Literal, Optional

from fastapi import APIRouter, Depends, HTTPException
from fastapi.responses import Response
from pydantic import BaseModel, Field

from ...core.config import settings
from ...core.logging import get_logger
from ...services.gemini_tts import gemini_tts_service
from ...core.dependencies import get_current_user

logger = get_logger(__name__)

router = APIRouter(prefix="/tts", tags=["tts"])


class VoicePreviewRequest(BaseModel):
    """Request to generate a voice preview"""
    voice_name: str
    language: str = "en"
    model: Literal["flash", "pro"] = "flash"
    speed: float = Field(default=1.0, ge=0.5, le=2.0)
    style_preset: Literal[
        "neutral", "calm", "energetic", "professional", "warm", "documentary", "custom"
    ] = "neutral"
    custom_style_prompt: Optional[str] = None


class VoicesResponse(BaseModel):
    """Available TTS voices"""
    voices: list[str]
    default: str


class LanguagesResponse(BaseModel):
    """Supported TTS languages"""
    languages: dict[str, str]  # code -> display name
    preview_samples: dict[str, str]  # code -> sample text


class TTSOptionItem(BaseModel):
    """Single option with value and label"""
    value: str
    label: str


class SpeedRange(BaseModel):
    """Speed slider range configuration"""
    min: float
    max: float
    default: float
    step: float


class TTSOptionsResponse(BaseModel):
    """Available TTS configuration options"""
    models: list[TTSOptionItem]
    style_presets: list[TTSOptionItem]
    speed_range: SpeedRange


@router.get("/voices", response_model=VoicesResponse)
async def list_voices(
    current_user=Depends(get_current_user)
) -> VoicesResponse:
    """
    List all available Gemini TTS voices.
    """
    return VoicesResponse(
        voices=settings.gemini_tts_voices,
        default=settings.gemini_tts_default_voice
    )


@router.get("/languages", response_model=LanguagesResponse)
async def list_languages(
    current_user=Depends(get_current_user)
) -> LanguagesResponse:
    """
    List all supported TTS languages with display names and preview samples.
    """
    return LanguagesResponse(
        languages=settings.gemini_tts_language_names,
        preview_samples=settings.gemini_tts_preview_samples
    )


@router.get("/options", response_model=TTSOptionsResponse)
async def get_tts_options(
    current_user=Depends(get_current_user)
) -> TTSOptionsResponse:
    """
    Get available TTS configuration options including models, style presets, and speed range.
    """
    return TTSOptionsResponse(
        models=[
            TTSOptionItem(value="flash", label="Flash (Fast, Cost-efficient)"),
            TTSOptionItem(value="pro", label="Pro (Higher Quality)"),
        ],
        style_presets=[
            TTSOptionItem(value="neutral", label="Neutral"),
            TTSOptionItem(value="calm", label="Calm & Soothing"),
            TTSOptionItem(value="energetic", label="Energetic"),
            TTSOptionItem(value="professional", label="Professional"),
            TTSOptionItem(value="warm", label="Warm & Friendly"),
            TTSOptionItem(value="documentary", label="Documentary"),
            TTSOptionItem(value="custom", label="Custom Prompt"),
        ],
        speed_range=SpeedRange(
            min=settings.gemini_tts_speed_min,
            max=settings.gemini_tts_speed_max,
            default=settings.gemini_tts_speed_default,
            step=settings.gemini_tts_speed_step
        )
    )


@router.post("/preview")
async def preview_voice(
    request: VoicePreviewRequest,
    current_user=Depends(get_current_user)
) -> Response:
    """
    Generate a voice preview audio sample with all TTS settings applied.
    Returns MP3 audio data.
    """
    # Validate voice name
    if request.voice_name not in settings.gemini_tts_voices:
        raise HTTPException(
            status_code=400,
            detail=f"Invalid voice name. Available voices: {', '.join(settings.gemini_tts_voices)}"
        )

    # Validate language
    if request.language not in settings.gemini_tts_languages:
        raise HTTPException(
            status_code=400,
            detail=f"Unsupported language. Available languages: {', '.join(settings.gemini_tts_languages.keys())}"
        )

    # Resolve style prompt from preset or custom
    if request.style_preset == "custom" and request.custom_style_prompt:
        style_prompt = request.custom_style_prompt
    else:
        style_prompt = settings.gemini_tts_style_prompts.get(request.style_preset, "")

    try:
        logger.info(
            f"Generating voice preview: voice={request.voice_name}, language={request.language}, "
            f"model={request.model}, speed={request.speed}x, style={request.style_preset}"
        )

        # Generate preview audio with all settings
        audio_data = await gemini_tts_service.synthesize_preview(
            voice_name=request.voice_name,
            language=request.language,
            model=request.model,
            speed=request.speed,
            style_prompt=style_prompt
        )

        return Response(
            content=audio_data,
            media_type="audio/mpeg",
            headers={
                "Content-Disposition": f"inline; filename=preview_{request.voice_name}_{request.language}.mp3"
            }
        )

    except Exception as e:
        logger.error(f"Voice preview generation failed: {e}")
        raise HTTPException(
            status_code=500,
            detail=f"Failed to generate voice preview: {str(e)}"
        ) from e
