"""
Pydantic schemas for Movie data model JSONFields.

These schemas validate the JSONFields on movie-related models:
- MovieTitle.metadata
- MovieTitle.genres (list validation)
- MoviePerson.metadata
- MovieCredit.metadata
- TMDb API response validation

SST Source: definitions/data/models/movies.yaml
Field Options: definitions/config/constraints/movie_options.yaml

Usage:
    from lightwave.schema.pydantic.models.movies import (
        MovieTitleMetadataSchema,
        MoviePersonMetadataSchema,
        MovieCreditMetadataSchema,
        TMDbMovieResponseSchema,
        TMDbSearchResultSchema,
    )
"""

from __future__ import annotations

from pydantic import Field

from lightwave.schema.pydantic.core.base import JSONFieldSchema


class MovieTitleMetadataSchema(JSONFieldSchema):
    """
    Schema for MovieTitle.metadata JSONField.

    Stores additional movie data that doesn't warrant its own column.
    Typically populated from TMDb API responses.

    Example:
        {
            "tmdb_genres": [{"id": 18, "name": "Drama"}],
            "production_countries": [{"iso_3166_1": "US", "name": "United States"}],
            "spoken_languages": [{"iso_639_1": "en", "name": "English"}],
            "tagline": "The true story of...",
            "budget": 20000000,
            "revenue": 150000000,
            "homepage": "https://example.com/movie",
            "imdb_genres": ["Drama", "Thriller"]
        }
    """

    tmdb_genres: list[dict[str, int | str]] = Field(
        default_factory=list,
        description="TMDb genre objects with id and name",
    )
    production_countries: list[dict[str, str]] = Field(
        default_factory=list,
        description="Production countries with ISO code and name",
    )
    spoken_languages: list[dict[str, str]] = Field(
        default_factory=list,
        description="Spoken languages with ISO code and name",
    )
    production_companies: list[dict[str, int | str | None]] = Field(
        default_factory=list,
        description="Production company objects",
    )
    tagline: str = Field("", description="Movie tagline")
    budget: int | None = Field(None, ge=0, description="Production budget in USD")
    revenue: int | None = Field(None, ge=0, description="Box office revenue in USD")
    homepage: str = Field("", description="Official movie website URL")
    imdb_genres: list[str] = Field(
        default_factory=list,
        description="Genre strings from IMDb bulk data (comma-separated in TSV)",
    )
    original_language: str = Field("", description="Original language ISO code")
    status: str = Field("", description="TMDb release status (Released, Post Production, etc.)")


class MoviePersonMetadataSchema(JSONFieldSchema):
    """
    Schema for MoviePerson.metadata JSONField.

    Stores additional person data from TMDb.

    Example:
        {
            "also_known_as": ["Roger Deakins", "Sir Roger Deakins"],
            "biography": "Sir Roger Deakins is a British cinematographer...",
            "place_of_birth": "Torquay, Devon, England, UK",
            "gender": 2,
            "imdb_known_for_titles": ["tt0120815", "tt1568346"]
        }
    """

    also_known_as: list[str] = Field(
        default_factory=list,
        description="Alternative names for this person",
    )
    biography: str = Field("", description="Biography text from TMDb")
    place_of_birth: str = Field("", description="Place of birth")
    gender: int | None = Field(
        None,
        ge=0,
        le=3,
        description="TMDb gender (0=not specified, 1=female, 2=male, 3=non-binary)",
    )
    imdb_known_for_titles: list[str] = Field(
        default_factory=list,
        description="IMDb title IDs this person is known for (from name.basics)",
    )
    imdb_primary_professions: list[str] = Field(
        default_factory=list,
        description="Primary professions from IMDb (e.g., cinematographer, director)",
    )


class MovieCreditMetadataSchema(JSONFieldSchema):
    """
    Schema for MovieCredit.metadata JSONField.

    Stores additional credit data from IMDb/TMDb.

    Example:
        {
            "imdb_category": "cinematographer",
            "imdb_job": "director of photography",
            "tmdb_credit_id": "52fe4250c3a36847f8014a11",
            "characters": ["Self"]
        }
    """

    imdb_category: str = Field("", description="IMDb title.principals category column")
    imdb_job: str = Field("", description="IMDb title.principals job column")
    tmdb_credit_id: str = Field("", description="TMDb credit ID for API lookups")
    characters: list[str] = Field(
        default_factory=list,
        description="Character names (for actors with multiple roles)",
    )


class TMDbMovieResponseSchema(JSONFieldSchema):
    """
    Schema for validating TMDb /movie/{id} API response.

    Used internally by the TMDb client to validate API responses
    before mapping to MovieTitle fields.
    """

    id: int = Field(..., description="TMDb movie ID")
    imdb_id: str | None = Field(None, description="IMDb ID")
    title: str = Field(..., description="Movie title")
    original_title: str = Field("", description="Original language title")
    overview: str = Field("", description="Plot summary")
    poster_path: str | None = Field(None, description="TMDb poster path (append to base URL)")
    backdrop_path: str | None = Field(None, description="TMDb backdrop path")
    release_date: str = Field("", description="Release date as YYYY-MM-DD string")
    runtime: int | None = Field(None, description="Runtime in minutes")
    vote_average: float = Field(0.0, ge=0, le=10, description="Vote average")
    vote_count: int = Field(0, ge=0, description="Vote count")
    popularity: float = Field(0.0, ge=0, description="Popularity score")
    adult: bool = Field(False, description="Adult content flag")
    genres: list[dict[str, int | str]] = Field(
        default_factory=list,
        description="Genre objects with id and name",
    )
    production_countries: list[dict[str, str]] = Field(
        default_factory=list,
        description="Production countries",
    )
    spoken_languages: list[dict[str, str]] = Field(
        default_factory=list,
        description="Spoken languages",
    )
    budget: int = Field(0, ge=0, description="Budget in USD")
    revenue: int = Field(0, ge=0, description="Revenue in USD")
    tagline: str = Field("", description="Movie tagline")
    homepage: str | None = Field(None, description="Official website")
    status: str = Field("", description="Release status")
    original_language: str = Field("", description="Original language ISO code")


class TMDbSearchResultSchema(JSONFieldSchema):
    """
    Schema for a single result from TMDb /search/movie API.

    Used to validate search responses before caching.
    """

    id: int = Field(..., description="TMDb movie ID")
    title: str = Field(..., description="Movie title")
    original_title: str = Field("", description="Original language title")
    overview: str = Field("", description="Plot summary")
    poster_path: str | None = Field(None, description="Poster path")
    backdrop_path: str | None = Field(None, description="Backdrop path")
    release_date: str = Field("", description="Release date YYYY-MM-DD")
    vote_average: float = Field(0.0, ge=0, le=10)
    vote_count: int = Field(0, ge=0)
    popularity: float = Field(0.0, ge=0)
    adult: bool = Field(False)
    genre_ids: list[int] = Field(default_factory=list, description="Genre ID list")


class TMDbPersonResponseSchema(JSONFieldSchema):
    """
    Schema for validating TMDb /person/{id} API response.
    """

    id: int = Field(..., description="TMDb person ID")
    imdb_id: str | None = Field(None, description="IMDb name ID")
    name: str = Field(..., description="Person name")
    also_known_as: list[str] = Field(default_factory=list)
    biography: str = Field("", description="Biography")
    birthday: str | None = Field(None, description="Birthday YYYY-MM-DD")
    deathday: str | None = Field(None, description="Death day YYYY-MM-DD")
    gender: int = Field(0, ge=0, le=3)
    known_for_department: str = Field("", description="Primary department")
    place_of_birth: str | None = Field(None)
    popularity: float = Field(0.0, ge=0)
    profile_path: str | None = Field(None, description="Profile image path")
