"""Pydantic schemas eksportowane przez API."""
from __future__ import annotations

import uuid
from datetime import date, datetime

from pydantic import BaseModel, ConfigDict


class StudioOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: uuid.UUID
    name: str
    slug: str
    network: str | None = None


class PerformerOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: uuid.UUID
    canonical_name: str
    slug: str
    gender: str | None = None
    as_alias: str | None = None


class TagOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: uuid.UUID
    name: str
    slug: str


class ExternalRefOut(BaseModel):
    source: str
    external_id: str
    url: str | None = None
    last_seen: datetime | None = None


class PlaybackSourceOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: uuid.UUID
    origin: str
    page_url: str
    embed_url: str | None = None
    stream_url: str | None = None
    quality: str | None = None
    duration_sec: int | None = None
    thumbnail_url: str | None = None
    animated_thumbnail_url: str | None = None


class SceneOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: uuid.UUID
    title: str
    slug: str | None = None
    release_date: date | None = None
    duration_sec: int | None = None
    description: str | None = None
    code: str | None = None
    director: str | None = None
    studio: StudioOut | None = None
    performers: list[PerformerOut] = []
    tags: list[TagOut] = []
    external_refs: list[ExternalRefOut] = []
    playback_sources: list[PlaybackSourceOut] = []
    # Kiedy scena trafiła do bazy (ingest). Używane przez mobile do oznaczenia
    # "NEW" na karcie scen w PerformerScenesScreen / StudioScenesScreen — gdy
    # `created_at > last_seen_at` (favorite) → badge.
    created_at: datetime | None = None
    # True = scena z masowego backfillu katalogu (deep-crawl). Mobile NIE pokazuje na niej
    # NEW badge nawet gdy created_at > last_seen, to stara treść, nie świeży release.
    backfill: bool = False
    # Watched indicator (z `scene_play_progress`): mobile dim'uje kafelek gdy
    # `finished=True`, pokazuje progress bar gdy `position_sec > 0`.
    last_played_at: datetime | None = None
    finished: bool = False
    position_sec: int = 0
    is_favorite: bool = False


class SceneListOut(BaseModel):
    items: list[SceneOut]
    total: int
    page: int
    per_page: int
    # has_more: czy istnieje kolejna strona. Liczone z fetcha per_page+1 (≈darmowe),
    # NIE z `total` — bo dla filtrowanych list `total` jest bounded ("1000+") żeby
    # uniknąć ~5s exhaustive count. Mobile paginuje po has_more, nie po total.
    has_more: bool = False
    # total_capped: True gdy `total` to bounded cap (są >total wyników). UI: "{total}+".
    total_capped: bool = False


class MovieChapterOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    chapter_index: int
    title: str | None = None
    start_sec: int | None = None
    end_sec: int | None = None
    scene_id: uuid.UUID | None = None


class MovieOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: uuid.UUID
    title: str
    slug: str | None = None
    release_year: int | None = None
    release_date: date | None = None
    duration_sec: int | None = None
    description: str | None = None
    director: str | None = None
    country: str | None = None
    rating: float | None = None
    poster_url: str | None = None
    backdrop_url: str | None = None
    studio: StudioOut | None = None
    performers: list[PerformerOut] = []
    tags: list[TagOut] = []
    chapters: list[MovieChapterOut] = []
    external_refs: list[ExternalRefOut] = []
    playback_sources: list[PlaybackSourceOut] = []
    # Used by mobile MoviesScreen NEW badge (created_at > client-stored seenSince)
    # and MovieDetail favorite star.
    created_at: datetime | None = None
    is_favorite: bool = False
    # Watched / continue-watching state (mirror SceneOut, bug-report b207ff17
    # 2026-05-26 "przydałoby się oznaczenie filmów już obejrzanych").
    last_played_at: datetime | None = None
    finished: bool = False
    position_sec: int = 0


class MovieListOut(BaseModel):
    items: list[MovieOut]
    total: int
    page: int
    per_page: int
