"""Creature display widget.

Shows the creature's ASCII art, name, emotion, and location.
Includes mood-based idle animation (breathing/bounce cycle).
"""

from __future__ import annotations

from textual.app import ComposeResult
from textual.reactive import reactive
from textual.timer import Timer
from textual.widget import Widget
from textual.widgets import Label, Static


# ── Creature art frames ──────────────────────────────────────────────
# Each life stage has two frames for idle animation.

CREATURE_FRAMES: dict[str, list[str]] = {
    "egg": [
        r"""
       ╭──────╮
      ╱ ·    · ╲
     │  ◠  ◠   │
     │    ◡     │
      ╲  ~~~~  ╱
       ╰──────╯
        """,
        r"""
       ╭──────╮
      ╱  ·  ·  ╲
     │  ◠  ◠   │
     │    ◡     │
      ╲  ~~~~  ╱
       ╰──────╯
        """,
    ],
    "hatchling": [
        r"""
        ∧  ∧
       (◕ ◡ ◕)
      ╭┤    ├╮
      │ ╰──╯ │
       ╲    ╱
        ╰╯╰╯
        """,
        r"""
        ∧  ∧
       (◕ ◡ ◕)
      ╭┤    ├╮
      │ ╰──╯ │
       ╲    ╱
        ╰──╯
        """,
    ],
    "juvenile": [
        r"""
         ∧  ∧
       ╭(◕ ◡ ◕)╮
       │ │    │ │
       │ ╰──╯  │
      ╱╲      ╱╲
     ╰╯ ╰────╯ ╰╯
        """,
        r"""
         ∧  ∧
       ╭(◕ ◡ ◕)╮
       │ │    │ │
       │ ╰────╯│
      ╱╲      ╱╲
     ╰╯ ╰────╯ ╰╯
        """,
    ],
    "adult": [
        r"""
          ∧    ∧
        ╭(◕  ◡  ◕)╮
       ╱│  │    │  │╲
      │ │  ╰────╯  │ │
      │ ╱          ╲ │
      ╰╯  ╱╲  ╱╲   ╰╯
          ╰╯  ╰╯
        """,
        r"""
          ∧    ∧
        ╭(◕  ◡  ◕)╮
       ╱│  │    │  │╲
      │ │  ╰────╯  │ │
      │╱            ╲│
      ╰╯  ╱╲  ╱╲   ╰╯
          ╰╯  ╰╯
        """,
    ],
}

# Mood-specific eye variants (replaces ◕ in frame text)
MOOD_EYES: dict[str, str] = {
    "joy": "◕",
    "excitement": "◕",
    "contentment": "◡",
    "curiosity": "◉",
    "anxiety": "◎",
    "sadness": "◔",
    "fear": "●",
    "anger": "◈",
    "loneliness": "◔",
    "trust": "◕",
}

# Map server life stage names to art frame keys
LIFE_STAGE_MAP: dict[str, str] = {
    "arrival": "hatchling",
    "settling": "hatchling",
    "growing": "juvenile",
    "establishing": "juvenile",
    "flourishing": "adult",
    "elder": "adult",
    # Direct matches (for tests or future use)
    "egg": "egg",
    "hatchling": "hatchling",
    "juvenile": "juvenile",
    "adult": "adult",
}

DEFAULT_FRAMES = CREATURE_FRAMES["hatchling"]


class CreatureDisplay(Widget):
    """Widget displaying the creature with name, emotion, and location.

    Runs a timer to cycle between two idle frames for a breathing effect.
    """

    DEFAULT_CSS = """
    CreatureDisplay {
        height: auto;
        min-height: 12;
        padding: 1 2;
        content-align: center middle;
    }
    CreatureDisplay .creature-art {
        text-align: center;
        color: $foreground;
    }
    CreatureDisplay .creature-name {
        text-align: center;
        color: $foreground;
        text-style: bold;
        padding: 1 0 0 0;
    }
    CreatureDisplay .creature-emotion {
        text-align: center;
        color: $primary;
    }
    CreatureDisplay .creature-location {
        text-align: center;
        color: $text-muted;
        text-style: italic;
    }
    """

    name: reactive[str] = reactive("???")
    life_stage: reactive[str] = reactive("hatchling")
    emotion_text: reactive[str] = reactive("")
    location_text: reactive[str] = reactive("")

    def __init__(self, **kwargs: object) -> None:
        super().__init__(**kwargs)
        self._frame_index = 0
        self._mood = ""
        self._anim_timer: Timer | None = None

    def compose(self) -> ComposeResult:
        art = self._get_frame(0)
        yield Static(art, classes="creature-art", id="creature-art")
        yield Label(self.name, classes="creature-name", id="creature-name")
        yield Label(self.emotion_text, classes="creature-emotion", id="creature-emotion")
        yield Label(self.location_text, classes="creature-location", id="creature-location")

    def on_mount(self) -> None:
        """Start the idle animation timer."""
        self._anim_timer = self.set_interval(1.5, self._tick_animation)

    def _tick_animation(self) -> None:
        """Advance to the next animation frame.

        Skips update when the parent screen is not the active screen
        to avoid wasting cycles on invisible widgets.
        """
        from sibilance.screens.dashboard import DashboardScreen

        if not isinstance(self.app.screen, DashboardScreen):
            return
        self._frame_index = 1 - self._frame_index
        try:
            art = self._get_frame(self._frame_index)
            self.query_one("#creature-art", Static).update(art)
        except Exception:
            pass

    def _get_frame(self, index: int) -> str:
        """Get the art frame for the current life stage, applying mood eyes."""
        art_key = LIFE_STAGE_MAP.get(self.life_stage, "hatchling")
        frames = CREATURE_FRAMES.get(art_key, DEFAULT_FRAMES)
        frame = frames[index % len(frames)].strip()

        # Apply mood-specific eyes if available
        if self._mood and self._mood in MOOD_EYES:
            eye = MOOD_EYES[self._mood]
            if eye != "◕":  # Only replace if different from default
                frame = frame.replace("◕", eye)

        return frame

    def watch_name(self, new_name: str) -> None:
        try:
            self.query_one("#creature-name", Label).update(new_name)
        except Exception:
            pass

    def watch_life_stage(self, new_stage: str) -> None:
        try:
            art = self._get_frame(self._frame_index)
            self.query_one("#creature-art", Static).update(art)
        except Exception:
            pass

    def watch_emotion_text(self, text: str) -> None:
        try:
            self.query_one("#creature-emotion", Label).update(text)
        except Exception:
            pass

    def watch_location_text(self, text: str) -> None:
        try:
            self.query_one("#creature-location", Label).update(text)
        except Exception:
            pass

    def update_from_status(self, name: str, life_stage: str, emotion_primary: str, location: str | None) -> None:
        """Convenience to update all fields from CreatureStatus."""
        self.name = name
        self.life_stage = life_stage
        self._mood = emotion_primary
        self.emotion_text = f"Feeling {emotion_primary}" if emotion_primary else ""
        self.location_text = location or ""
