from typing import Any

from pydantic import BaseModel, field_validator

from ..models.job import (
    AccessibleVideoProgressItem,
    JobFailure,
    JobStatus,
    LangOutput,
    RequestedOutputs,
    Review,
    TTSPreferences,
)
from ..schemas.accessible_video import AccessibleVideoMethod


class JobResponse(BaseModel):
    id: str
    client_id: str | None = None  # ID of the user who created the job
    title: str
    status: JobStatus
    source: dict[str, Any]
    requested_outputs: RequestedOutputs
    review: Review
    outputs: dict[str, LangOutput] | None = None
    accessible_video_progress: dict[str, AccessibleVideoProgressItem] | None = None
    failure: JobFailure | None = None
    error: dict[str, Any] | None = None
    created_at: str | None = None
    updated_at: str | None = None
    created_by_name: str | None = None  # User's full_name who created the job
    cost_tracker_project_id: str | None = None


class JobListResponse(BaseModel):
    jobs: list[JobResponse]
    total: int
    page: int
    size: int


class JobCreateRequest(BaseModel):
    title: str
    requested_outputs: RequestedOutputs


class JobUpdateRequest(BaseModel):
    title: str | None = None
    review_notes: str | None = None
    cost_tracker_project_id: str | None = None


class ApproveEnglishRequest(BaseModel):
    notes: str | None = None


class ApproveSourceRequest(BaseModel):
    """Request to approve source language content (works for any language)"""
    notes: str | None = None
    tts_preferences: TTSPreferences | None = None  # Override TTS voice settings
    accessible_video_method: AccessibleVideoMethod | None = None  # User-selected method for accessible video


class UpdateTTSPreferencesRequest(BaseModel):
    """Request to update TTS preferences and regenerate all TTS segments"""
    tts_preferences: TTSPreferences


class RejectJobRequest(BaseModel):
    notes: str


class CompleteJobRequest(BaseModel):
    notes: str | None = None


class VttUpdateRequest(BaseModel):
    captions_vtt: str | None = None
    audio_description_vtt: str | None = None
    language: str | None = None  # If None, defaults to source language
    if_match: str | None = None  # Optimistic locking — SHA1 of expected current content
    retranslate_languages: bool = False  # Re-translate all target languages from updated source VTT
    note: str | None = None  # Optional save message shown in version history

    @field_validator('captions_vtt', 'audio_description_vtt', mode='before')
    @classmethod
    def empty_str_to_none(cls, v: Any) -> str | None:
        return None if v == '' else v


class VttTimingAdjustRequest(BaseModel):
    offset_seconds: float
    language: str = "en"
    adjust_captions: bool = True
    adjust_audio_description: bool = True


class JobDownloadsResponse(BaseModel):
    downloads: dict[str, dict[str, str] | str]  # language -> {file_type: signed_url} OR source_video -> signed_url


class VttContentResponse(BaseModel):
    captions_vtt: str | None = None
    audio_description_vtt: str | None = None
    retimed_captions_vtt: str | None = None  # Re-timed captions for accessible videos
    etag: str | None = None  # SHA1 hash for optimistic locking (If-Match on PATCH)


class AssetValidationResponse(BaseModel):
    is_valid: bool
    errors: list[str]
    warnings: list[str] = []


class JobDeleteResponse(BaseModel):
    message: str


class BulkDeleteRequest(BaseModel):
    job_ids: list[str]


class BulkDeleteResponse(BaseModel):
    deleted_count: int
    total_requested: int
    errors: list[str]


class BulkApproveRequest(BaseModel):
    """Request to bulk approve multiple jobs with optional settings"""
    job_ids: list[str]
    notes: str | None = None
    accessible_video_method: AccessibleVideoMethod | None = None  # Method for accessible video
    tts_preferences: TTSPreferences | None = None


class BulkApproveResponse(BaseModel):
    """Response for bulk approval operation"""
    approved_count: int
    total_requested: int
    errors: list[str]


class ReturnToQCRequest(BaseModel):
    notes: str


class BulkReturnToQCRequest(BaseModel):
    job_ids: list[str]
    notes: str


class BulkReturnToQCResponse(BaseModel):
    returned_count: int
    total_requested: int
    errors: list[str]


class BulkDownloadRequest(BaseModel):
    """Request to download multiple jobs as a single zip file"""
    job_ids: list[str]


class BlockedOnSourceRequest(BaseModel):
    reason: str  # brief description of what is wrong with the source video


class PromoteToQCRequest(BaseModel):
    notes: str = ""  # optional context for the QC team


# ── PR-3: Resumable / chunked upload ──────────────────────────────────────────

class UploadInitRequest(BaseModel):
    filename: str
    content_type: str
    file_size: int  # bytes — validated server-side against settings.upload_max_video_bytes


class UploadInitResponse(BaseModel):
    job_id: str
    upload_url: str  # GCS resumable session URI — browser uploads chunks directly here


class UploadCompleteRequest(BaseModel):
    job_id: str
    title: str
    original_filename: str
    requested_outputs: dict
    brand_context: str | None = None
    project_id: str | None = None
    brief_id: str | None = None
    deadline: str | None = None
    initial_linguist_id: str | None = None
    initial_reviewer_id: str | None = None


class RetranslateLanguageRequest(BaseModel):
    language: str
    reason: str | None = None
