from datetime import datetime
from enum import Enum
from typing import Any, Literal, Optional

from pydantic import BaseModel, Field, constr


class JobStatus(str, Enum):
    CREATED = "created"
    INGESTING = "ingesting"
    AI_PROCESSING = "ai_processing"
    PENDING_QC = "pending_qc"
    APPROVED_ENGLISH = "approved_english"  # For English source videos
    APPROVED_SOURCE = "approved_source"    # For non-English source videos
    REJECTED = "rejected"
    QC_FEEDBACK = "qc_feedback"
    TRANSLATING = "translating"
    TTS_GENERATING = "tts_generating"
    PENDING_FINAL_REVIEW = "pending_final_review"
    COMPLETED = "completed"

    @classmethod
    def is_approved(cls, status: str) -> bool:
        """Check if status indicates source approval (any language)"""
        return status in [cls.APPROVED_ENGLISH.value, cls.APPROVED_SOURCE.value]


class Source(BaseModel):
    filename: str
    original_filename: Optional[str] = None
    gcs_uri: str
    duration_s: Optional[float] = None
    language: constr(min_length=2, max_length=10) = "en"  # Final source language (from detection or explicit)
    language_hint: Optional[str] = None  # User-provided hint for non-English videos
    detected_language: Optional[str] = None  # AI-detected language from Gemini


class TTSPreferences(BaseModel):
    """TTS voice preferences for audio description generation"""
    provider: Literal["gemini", "google", "elevenlabs"] = "gemini"
    default_voice: str = "Kore"  # Default Gemini voice
    voices_per_language: dict[str, str] = {}  # {"en": "Kore", "es": "Aoede"}
    # TTS quality and style settings
    model: Literal["flash", "pro"] = "flash"  # flash = fast/cheap, pro = higher quality
    speed: float = Field(default=1.0, ge=0.5, le=2.0)  # Speech rate multiplier
    style_preset: Literal[
        "neutral", "calm", "energetic", "professional", "warm", "documentary", "custom"
    ] = "neutral"
    custom_style_prompt: Optional[str] = None  # Used when style_preset is "custom"


class RequestedOutputs(BaseModel):
    captions_vtt: bool = True
    audio_description_vtt: bool = True
    audio_description_mp3: bool = True
    languages: list[str] = []
    transcreation: list[str] = []
    tts_preferences: Optional[TTSPreferences] = None


class LangOutput(BaseModel):
    captions_vtt_gcs: Optional[str] = None
    ad_vtt_gcs: Optional[str] = None
    ad_mp3_gcs: Optional[str] = None
    origin: Optional[Literal["translate", "transcreate"]] = None
    qa_notes: Optional[str] = None


class ReviewHistoryItem(BaseModel):
    at: datetime
    status: str
    by: Optional[str] = None
    notes: Optional[str] = None


class Review(BaseModel):
    notes: Optional[str] = ""
    reviewer_id: Optional[str] = None
    history: list[ReviewHistoryItem] = []


class AISection(BaseModel):
    ingestion_json: Optional[dict[str, Any]] = None
    confidence: Optional[float] = None


class Job(BaseModel):
    id: Optional[str] = Field(None, alias="_id")
    client_id: str
    title: str
    source: Source
    requested_outputs: RequestedOutputs
    status: JobStatus = JobStatus.CREATED
    review: Review = Review()
    outputs: Optional[dict[str, LangOutput]] = None
    ai: Optional[AISection] = None
    error: Optional[dict[str, Any]] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    class Config:
        populate_by_name = True
        use_enum_values = True


class JobCreate(BaseModel):
    title: str
    source_is_english: bool = True  # True = English source, False = other language (auto-detect)
    language_hint: Optional[str] = None  # Optional hint when source_is_english=False
    requested_outputs: RequestedOutputs


class JobUpdate(BaseModel):
    title: Optional[str] = None
    status: Optional[JobStatus] = None
    review: Optional[Review] = None
    outputs: Optional[dict[str, LangOutput]] = None
    ai: Optional[AISection] = None
    error: Optional[dict[str, Any]] = None
