from fastapi import APIRouter, Depends, HTTPException
from fastapi.responses import Response
from pydantic import BaseModel
from sqlalchemy.orm import Session

from app.config import settings
from app.database import get_db
from app.models.user import User
from app.models.ai_model_config import AIModelConfig
from app.services import ai_service
from app.utils.auth import get_current_user, check_rate_limit

router = APIRouter()


class TTSRequest(BaseModel):
    text: str
    voice: str | None = None  # model_id override


def _polly_enabled() -> bool:
    try:
        import redis as redis_lib
        r = redis_lib.from_url(settings.REDIS_URL, decode_responses=True)
        val = r.get("settings:polly_enabled")
        return val != "false"
    except Exception:
        return True


@router.get("/voices")
def get_voices(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """Return available TTS voices from DB, excluding Polly if disabled."""
    query = db.query(AIModelConfig).filter(
        AIModelConfig.task == "tts",
        AIModelConfig.is_active == True,
    )
    if not _polly_enabled():
        query = query.filter(~AIModelConfig.model_id.like("polly/%"))
    db_models = query.order_by(AIModelConfig.is_default.desc(), AIModelConfig.name).all()
    return [{"id": m.model_id, "name": m.name, "is_default": m.is_default} for m in db_models]


@router.post("/speak")
def text_to_speech(
    request: TTSRequest,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """Convert text to speech using configured or user-selected TTS model."""
    # Rate limit: 60 TTS requests per user per hour (admins/unthrottled users exempt)
    check_rate_limit(
        key=f"tts_speak:{current_user.id}",
        max_calls=60,
        window_seconds=3600,
        detail="You've reached the audio limit (60 clips/hour). The limit resets automatically — try again shortly. Contact an admin if you need this raised.",
        user=current_user,
    )
    if not request.text.strip():
        raise HTTPException(status_code=400, detail="Text cannot be empty")

    text = request.text[:2000]

    if request.voice:
        if request.voice.startswith("polly/") and not _polly_enabled():
            raise HTTPException(status_code=400, detail="AWS Polly is currently disabled")
        config = db.query(AIModelConfig).filter(AIModelConfig.model_id == request.voice).first()
        model_id = config.model_id if config else request.voice
        api_key = config.api_key if (config and config.api_key) else None
    else:
        config = db.query(AIModelConfig).filter(
            AIModelConfig.task == "tts",
            AIModelConfig.is_active == True,
            AIModelConfig.is_default == True,
        ).first()
        model_id = config.model_id if config else "tts-1:alloy"
        api_key = config.api_key if (config and config.api_key) else None

    audio = ai_service.generate_tts_audio(text, model_id=model_id, api_key=api_key)
    if audio is None:
        raise HTTPException(status_code=500, detail="TTS generation failed. Check model configuration.")

    return Response(content=audio, media_type="audio/mpeg")
