"""Pure domain models shared across application boundaries."""

from dataclasses import dataclass
from enum import StrEnum


@dataclass(frozen=True)
class Track:
    """A Spotify track expressed without transport-specific data."""

    id: str
    uri: str
    title: str
    artists: tuple[str, ...]
    album_name: str
    album_art_url: str | None
    external_url: str | None


@dataclass(frozen=True)
class TrackCandidate:
    """A title and artist pair proposed for Spotify resolution."""

    title: str
    artist: str


@dataclass(frozen=True)
class ConversationTurn:
    """One bounded user or assistant message supplied by the client."""

    role: str
    content: str


@dataclass(frozen=True)
class PreviousRecommendation:
    """One earlier recommendation available to a refinement request."""

    rank: int
    track_id: str
    title: str
    artists: tuple[str, ...]


class Familiarity(StrEnum):
    """How strongly a request should favor known or unknown music."""

    FAMILIAR = "familiar"
    MIX = "mix"
    NEW = "new"


@dataclass(frozen=True)
class Intent:
    """Structured interpretation and candidate set for a discovery query."""

    mood: tuple[str, ...]
    activity: str | None
    era: tuple[str, ...]
    languages: tuple[str, ...]
    genres: tuple[str, ...]
    familiarity: Familiarity
    is_refinement: bool
    intent_summary: str
    candidates: tuple[TrackCandidate, ...]


@dataclass(frozen=True)
class RerankSelection:
    """One grounded track selected by the recommender."""

    track_id: str
    justification: str


@dataclass(frozen=True)
class TasteProfile:
    """Bounded Spotify taste signals collected for one session."""

    short_term_artists: tuple[str, ...]
    long_term_artists: tuple[str, ...]
    short_term_tracks: tuple[Track, ...]
    long_term_tracks: tuple[Track, ...]
    saved_tracks: tuple[Track, ...]


@dataclass(frozen=True)
class CompressedTasteProfile:
    """Prompt-ready taste text plus exact known Spotify track identifiers."""

    text: str
    known_track_ids: frozenset[str]


@dataclass(frozen=True)
class CreatedPlaylist:
    """The application-owned result of creating a Spotify playlist."""

    id: str
    url: str
