"""Response types for the Sibilance API.

All types mirror the server's JSON responses as Python dataclasses.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Literal


# ── Auth Types ──────────────────────────────────────────────────────────


@dataclass(frozen=True, slots=True)
class DeviceCodeResponse:
    code: str
    device_id: str
    verify_url: str
    expires_at: str
    expires_in: int


@dataclass(frozen=True, slots=True)
class DeviceAuthStatus:
    status: Literal["pending", "confirmed", "expired"]
    token: str | None = None
    observer_id: str | None = None
    display_name: str | None = None


@dataclass(frozen=True, slots=True)
class AuthRequirements:
    requires_access_code: bool


@dataclass(frozen=True, slots=True)
class ObserverProfile:
    id: str
    display_name: str
    email: str | None = None
    avatar_url: str | None = None
    provider: str | None = None
    created_at: str = ""


# ── Creature Types ──────────────────────────────────────────────────────


@dataclass(frozen=True, slots=True)
class Emotion:
    primary: str
    secondary: list[str] = field(default_factory=list)
    intensity: float = 0.0
    valence: float = 0.0


@dataclass(frozen=True, slots=True)
class EmotionBrief:
    primary: str
    intensity: float = 0.0


@dataclass(frozen=True, slots=True)
class Bond:
    trust: float = 0.0
    understanding: float = 0.0
    influence: float = 0.0
    resonance: float = 0.0
    score: float = 0.0
    last_interaction: str = ""


@dataclass(frozen=True, slots=True)
class BondWithLevel:
    trust: float = 0.0
    understanding: float = 0.0
    influence: float = 0.0
    resonance: float = 0.0
    level: str = ""


@dataclass(frozen=True, slots=True)
class BondImpact:
    trust: float = 0.0
    understanding: float = 0.0
    influence: float = 0.0
    resonance: float = 0.0


@dataclass(frozen=True, slots=True)
class Needs:
    hunger: float = 0.0
    energy: float = 0.0
    comfort: float = 0.0
    curiosity: float = 0.0
    social: float = 0.0


@dataclass(frozen=True, slots=True)
class UrgentNeed:
    need: str
    dimension: str
    value: float
    severity: str


@dataclass(frozen=True, slots=True)
class PendingQuestion:
    question: str
    context: str
    type: str


@dataclass(frozen=True, slots=True)
class Skills:
    building: float = 0.0
    foraging: float = 0.0
    social: float = 0.0
    exploration: float = 0.0
    craft: float = 0.0
    nurture: float = 0.0


@dataclass(frozen=True, slots=True)
class Nature:
    dominant_trait: str = ""
    temperament: str = ""
    aptitude_hint: str = ""
    quirk: str = ""


@dataclass(frozen=True, slots=True)
class NatureBrief:
    dominant_trait: str = ""
    temperament: str = ""


@dataclass(frozen=True, slots=True)
class StoryArc:
    title: str
    type: str
    tension: float
    status: str


@dataclass(frozen=True, slots=True)
class Territory:
    name: str
    condition: float
    improvements: int
    location: str


@dataclass(frozen=True, slots=True)
class SleepState:
    is_asleep: bool
    sleep_hour: float
    wake_hour: float


@dataclass(frozen=True, slots=True)
class CreatureStatus:
    agent_id: str
    name: str
    is_active: bool
    is_dormant: bool
    unnamed: bool
    life_stage: str
    location: str | None = None
    emotion: Emotion | None = None
    bond: Bond | None = None
    needs: Needs | None = None
    urgent_need: UrgentNeed | None = None
    pending_question: PendingQuestion | None = None
    skills: Skills | None = None
    nature: Nature | None = None
    story_arcs: list[StoryArc] = field(default_factory=list)
    territories: list[Territory] = field(default_factory=list)
    sleep: SleepState | None = None


# ── Creature Action Responses ───────────────────────────────────────────


@dataclass(frozen=True, slots=True)
class HatchResponse:
    agent_id: str
    temp_name: str
    starting_location: str
    nature: Nature
    personality: PersonalityBrief | None = None
    emotional_state: EmotionalStateBrief | None = None


@dataclass(frozen=True, slots=True)
class PersonalityBrief:
    archetype: str
    dominant: list[str] = field(default_factory=list)


@dataclass(frozen=True, slots=True)
class EmotionalStateBrief:
    primary_emotion: str
    secondary_emotions: list[str] = field(default_factory=list)
    intensity: float = 0.0


@dataclass(frozen=True, slots=True)
class NameResponse:
    success: bool
    name: str
    agent_id: str


@dataclass(frozen=True, slots=True)
class GuidanceResponse:
    success: bool
    guidance_type: str
    response: str


@dataclass(frozen=True, slots=True)
class TalkResponse:
    response: str
    creature_name: str
    emotion: EmotionBrief | None = None
    bond_impact: BondImpact | None = None
    care_quality: float = 0.0


@dataclass(frozen=True, slots=True)
class FeedResponse:
    reaction: str
    creature_name: str
    emotion: EmotionBrief | None = None
    bond_impact: BondImpact | None = None
    care_quality: float = 0.0


@dataclass(frozen=True, slots=True)
class RecentEvent:
    original_event_type: str
    creature_description: str
    share_willingness: float = 0.0
    emotional_color: str = ""
    is_embellished: bool = False


@dataclass(frozen=True, slots=True)
class LookResponse:
    creature_name: str
    life_stage: str
    location: str | None = None
    emotion: Emotion | None = None
    bond: BondWithLevel | None = None
    recent_events: list[RecentEvent] = field(default_factory=list)
    absence_hours: float = 0.0
    nature: NatureBrief | None = None


@dataclass(frozen=True, slots=True)
class CareHistoryEntry:
    type: str
    quality: float
    timestamp: str


@dataclass(frozen=True, slots=True)
class CreatureLog:
    creature_name: str
    events: list[RecentEvent] = field(default_factory=list)
    care_history: list[CareHistoryEntry] = field(default_factory=list)
    bond_level: str = ""


# ── Social Types ────────────────────────────────────────────────────────


@dataclass(frozen=True, slots=True)
class Friend:
    agent_id: str
    name: str
    is_active: bool
    relationship: str
    interactions: int = 0
    last_seen: str | None = None


@dataclass(frozen=True, slots=True)
class FavorBalance:
    friend_id: str
    friend_name: str
    given: int = 0
    received: int = 0
    balance: int = 0


@dataclass(frozen=True, slots=True)
class FriendsResponse:
    friends: list[Friend] = field(default_factory=list)
    favors: list[FavorBalance] = field(default_factory=list)


# ── Journal Types ───────────────────────────────────────────────────────


@dataclass(frozen=True, slots=True)
class JournalEntry:
    id: str
    timestamp: str
    content: str
    tags: list[str] = field(default_factory=list)
    is_private: bool = False


@dataclass(frozen=True, slots=True)
class JournalResponse:
    entries: list[JournalEntry] = field(default_factory=list)
    trust_level: float = 0.0


# ── Den / Territory Types ──────────────────────────────────────────────


@dataclass(frozen=True, slots=True)
class DenImprovement:
    name: str
    type: str
    description: str


@dataclass(frozen=True, slots=True)
class Den:
    id: str
    name: str
    location: str
    condition: float
    description: str | None = None
    improvements: list[DenImprovement] = field(default_factory=list)


@dataclass(frozen=True, slots=True)
class DenResponse:
    dens: list[Den] = field(default_factory=list)


# ── Sleep Types ─────────────────────────────────────────────────────────


@dataclass(frozen=True, slots=True)
class SleepSchedule:
    sleep_hour: float
    wake_hour: float
    is_asleep: bool
    current_world_hour: float


@dataclass(frozen=True, slots=True)
class SleepScheduleUpdate:
    success: bool
    sleep_hour: float
    wake_hour: float


# ── Gift Types ──────────────────────────────────────────────────────────


@dataclass(frozen=True, slots=True)
class GiftResponse:
    success: bool
    response: str
    bond_impact: BondImpact | None = None


# ── Billing Types ───────────────────────────────────────────────────────


@dataclass(frozen=True, slots=True)
class CheckoutResponse:
    url: str


@dataclass(frozen=True, slots=True)
class CheckoutStatus:
    status: Literal["pending", "paid"]
    subscription_status: str | None = None
    creature_count: int | None = None


@dataclass(frozen=True, slots=True)
class SubscriptionStatus:
    has_subscription: bool
    status: str | None = None
    creature_count: int | None = None
    current_period_end: str | None = None
    payment_method_saved: bool | None = None


@dataclass(frozen=True, slots=True)
class CreatureCountResponse:
    success: bool
    creature_count: int


@dataclass(frozen=True, slots=True)
class PortalResponse:
    url: str


@dataclass(frozen=True, slots=True)
class AgentListItem:
    id: str
    name: str
    is_dormant: bool | None = None


# ── World State Types ──────────────────────────────────────────────────


@dataclass(frozen=True, slots=True)
class WorldTime:
    day: int
    hour: int
    minute: int
    period: str
    season: str
    day_of_week: str
    day_of_week_index: int
    formatted: str = ""


@dataclass(frozen=True, slots=True)
class LocationEvent:
    id: str
    location_name: str
    description: str
    duration: float = 0.0
    emotional_cue: str = ""
    started_at: float = 0.0


@dataclass(frozen=True, slots=True)
class WorldState:
    time: WorldTime
    weather: str = ""
    weather_description: str = ""
    global_mood: float = 0.0
    active_events: list[LocationEvent] = field(default_factory=list)


# ── WebSocket Message Types ─────────────────────────────────────────────


@dataclass(frozen=True, slots=True)
class WSConnected:
    message: str
    timestamp: int


@dataclass(frozen=True, slots=True)
class WSLocationUpdate:
    location: str


@dataclass(frozen=True, slots=True)
class WSWorldStateUpdate:
    data: dict[str, object]


@dataclass(frozen=True, slots=True)
class WSMysteryClue:
    data: list[str]


@dataclass(frozen=True, slots=True)
class WSRareEvent:
    data: list[str]


@dataclass(frozen=True, slots=True)
class WSKafkaEvent:
    topic: str
    data: dict[str, object]
