from typing import Literal

from pydantic import BaseModel, Field, model_validator


class LoginSchema(BaseModel):
    force: bool = False  # True = login again even if session exists


class ExchangeSearchSchema(BaseModel):
    query: str = Field(..., min_length=1, examples=["Detroit"])


class ExchangeTypeSchema(BaseModel):
    """
    team_id: opponent from GET /exchange/data (suggested) or GET /exchange/search/teams (search)
    owner_team_id: our Hudl team (Football / Basketball) — opens /manage/exchanges/{owner}
    team_source: which list the opponent came from
    exchange_type: two-way | one-way | request
    """
    team_id: str = Field(..., examples=["<dynamic_from_playwright>"])
    team_source: Literal["suggested", "search"]
    exchange_type: Literal["two-way", "one-way", "request"]
    owner_team_id: str | None = Field(
        None,
        examples=["<dynamic_from_playwright>"],
        description="Selected org team (Football/Basketball) Hudl id",
    )


class VideoSelectSchema(BaseModel):
    """
    video_indices: List of indices from GET /exchange/videos to select.
    """
    video_indices: list[int] = Field(..., examples=[[0, 2]])


class PlaylistSelectSchema(BaseModel):
    """playlist_indices from the Choose Playlist(s) step (Football multi-step)."""
    playlist_indices: list[int] = Field(default_factory=list, examples=[[0]])


class StatsSchema(BaseModel):
    include_stats: bool = Field(False, examples=[True])
    include_team_stats: bool = Field(True, examples=[True])
    include_player_stats: bool = Field(True, examples=[True])


class NotesSchema(BaseModel):
    message: str | None = Field(None, examples=["Here are the requested videos"])


class DeleteFileSchema(BaseModel):
    file_index: int = Field(..., examples=[0])


class VideoDetailsSchema(BaseModel):
    schedule_event_index: int | None = Field(None, examples=[2])
    video_type: Literal["Game", "Practice", "Scout"] = Field("Game")
    title: str | None = Field(None, examples=["My Custom Title"])
    check_event: bool = Field(False)


class CancelSchema(BaseModel):
    step_index: int = Field(..., examples=[1])


class BackSchema(BaseModel):
    back_index: int = Field(..., examples=[1])


class ActiveExchangeDetailsSchema(BaseModel):
    name: str = Field(..., examples=["Ed White High School"])
    index: int = Field(default=0, ge=0, examples=[0])
    exchange_id: str | None = Field(default=None, examples=["6a1439c41a1e880488caec21"])
    href: str | None = Field(
        default=None,
        examples=["/teams/{team_id}/exchanges/6a1439c41a1e880488caec21"],
    )
    team_id: str | None = Field(None, examples=["<dynamic_from_playwright>"])


class ActiveExchangeActionSchema(ActiveExchangeDetailsSchema):
    action_type: Literal["delete", "cancel", "decline", "choose", "add"] = Field(
        ..., examples=["cancel"]
    )


class VideoStreamSchema(BaseModel):
    watch_url: str = Field(..., examples=["https://app.hudl.com/watch/team/..."])


class LibraryActionBaseSchema(BaseModel):
    video_index: int = Field(..., examples=[0])


class LibraryUpdateTypeSchema(LibraryActionBaseSchema):
    video_type: Literal["Game", "Scout", "Practice"] = Field("Game")


class LibraryUpdateEventSchema(LibraryActionBaseSchema):
    event_name: str = Field(..., examples=["None"])


class LibraryRenameSchema(LibraryActionBaseSchema):
    new_name: str | None = Field(None, examples=["New Video Name"])
    cancel: bool = Field(False)


class LibraryEmailDownloadSchema(LibraryActionBaseSchema):
    option: Literal["video_and_stats", "video_only"] = Field("video_and_stats")
    cancel: bool = Field(False)


class LibraryDownloadToMediaSchema(LibraryActionBaseSchema):
    """Download a Hudl library video and persist it under media/{id}/."""

    title: str = Field(..., examples=["Utica vs Powers Catholic"])
    watch_url: str = Field(..., examples=["https://app.hudl.com/watch/team/..."])


class LibraryDownloadByRefSchema(BaseModel):
    """Download by library tile index or Hudl watch URL `v` id. Send either one."""

    video_index: int | None = Field(None, examples=[0])
    v: str | None = Field(
        None,
        examples=["95304146", "VmlkZW82YTUwOTA3MGJmN2NlYzQ5Njk4M2IwNmU"],
        description="Hudl video id from ?v= (numeric or encoded; trailing = optional)",
    )

    @model_validator(mode="after")
    def require_video_index_or_v(self):
        has_index = self.video_index is not None
        has_v = bool((self.v or "").strip())
        if not has_index and not has_v:
            raise ValueError("Provide either video_index or v")
        return self


class ManageLibraryDownloadItemSchema(BaseModel):
    path: list[str] = Field(default_factory=list, description="Folder labels from season to parent folder")
    label: str = Field(..., examples=["Communication/Cadence"])


class ManageLibraryDownloadSchema(BaseModel):
    team_id: str | None = Field(None, examples=["<dynamic_from_playwright>"])
    season: str = Field(..., examples=["2026-2027 Season"])
    items: list[ManageLibraryDownloadItemSchema]
    format: Literal["multiple", "single", "presentation"] = Field("multiple")
    include_breakdown: bool = Field(True)


class ManageLibrarySelectSchema(BaseModel):
    team_id: str | None = Field(None, examples=["<dynamic_from_playwright>"])
    season: str = Field(..., examples=["2026-2027 Season"])
    path: list[str] = Field(default_factory=list, description="Folder labels from season to parent folder")
    label: str = Field(..., examples=["Communication/Cadence"])
    selected: bool = Field(True, description="True to check the clip, False to uncheck it")


class ManageLibraryClipMetaSchema(BaseModel):
    team_id: str | None = Field(None, examples=["<dynamic_from_playwright>"])
    season: str = Field(..., examples=["2022-2023 Season"])
    path: list[str] = Field(default_factory=list, description="Folder labels from season to parent folder")
    label: str = Field(..., examples=["*** Alabama Defense (Derrick Ansley) #2 ***"])


class SwitchHudlTeamSchema(BaseModel):
    team_name: str = Field(..., examples=["<team_name_from_switcher>"])
    org_name: str | None = Field(None, examples=["<org_name_from_switcher>"])
    team_id: str | None = Field(
        None,
        examples=["<dynamic_from_playwright>"],
        description="Optional Hudl numeric team id — preferred over name match",
    )


class OpenExchangeSchema(BaseModel):
    team_id: str | None = Field(None, examples=["<dynamic_from_playwright>"])
