"""Stat bar widgets for bond dimensions and creature needs.

Each bar renders as a labeled progress bar with a value label.
Uses Textual's ProgressBar with custom CSS classes for per-dimension coloring.
"""

from __future__ import annotations

from textual.app import ComposeResult
from textual.reactive import reactive
from textual.widget import Widget
from textual.widgets import Label, ProgressBar


class StatBar(Widget):
    """A single labeled stat bar (0.0 - 1.0 range)."""

    DEFAULT_CSS = """
    StatBar {
        height: 1;
        layout: horizontal;
    }
    StatBar .stat-label {
        width: 14;
        color: $text;
    }
    StatBar ProgressBar {
        width: 1fr;
    }
    StatBar .stat-value {
        width: 5;
        text-align: right;
        color: $text-muted;
    }
    """

    value: reactive[float] = reactive(0.0)
    label_text: reactive[str] = reactive("")

    def __init__(
        self,
        label: str,
        value: float = 0.0,
        css_class: str = "",
        **kwargs: object,
    ) -> None:
        super().__init__(**kwargs)
        self.label_text = label
        self.value = value
        self._css_class = css_class

    def compose(self) -> ComposeResult:
        yield Label(self.label_text, classes="stat-label")
        bar = ProgressBar(total=100, show_eta=False, show_percentage=False)
        if self._css_class:
            bar.add_class(self._css_class)
        yield bar
        yield Label(self._format_value(), classes="stat-value")

    def _format_value(self) -> str:
        return f"{self.value:.0%}" if self.value <= 1.0 else f"{self.value:.0f}"

    def watch_value(self, new_value: float) -> None:
        try:
            bar = self.query_one(ProgressBar)
            bar.progress = new_value * 100
            lbl = self.query_one(".stat-value", Label)
            lbl.update(self._format_value())
        except Exception:
            pass


class BondPanel(Widget):
    """Panel showing all four bond dimensions."""

    DEFAULT_CSS = """
    BondPanel {
        height: auto;
        padding: 0 1;
    }
    BondPanel .panel-header {
        color: #4ecdc4;
        text-style: bold;
        padding: 0 0 1 0;
    }
    """

    trust: reactive[float] = reactive(0.0)
    understanding: reactive[float] = reactive(0.0)
    influence: reactive[float] = reactive(0.0)
    resonance: reactive[float] = reactive(0.0)

    def compose(self) -> ComposeResult:
        yield Label("Bond", classes="panel-header")
        yield StatBar("Trust", self.trust, css_class="bar-bond", id="bar-trust")
        yield StatBar(
            "Understanding", self.understanding, css_class="bar-bond", id="bar-understanding"
        )
        yield StatBar(
            "Influence", self.influence, css_class="bar-bond", id="bar-influence"
        )
        yield StatBar(
            "Resonance", self.resonance, css_class="bar-bond", id="bar-resonance"
        )

    def update_bond(
        self,
        trust: float,
        understanding: float,
        influence: float,
        resonance: float,
    ) -> None:
        self.trust = trust
        self.understanding = understanding
        self.influence = influence
        self.resonance = resonance
        try:
            self.query_one("#bar-trust", StatBar).value = trust
            self.query_one("#bar-understanding", StatBar).value = understanding
            self.query_one("#bar-influence", StatBar).value = influence
            self.query_one("#bar-resonance", StatBar).value = resonance
        except Exception:
            pass


class NeedsPanel(Widget):
    """Panel showing all five creature needs."""

    DEFAULT_CSS = """
    NeedsPanel {
        height: auto;
        padding: 0 1;
    }
    NeedsPanel .panel-header {
        color: #ff6b6b;
        text-style: bold;
        padding: 0 0 1 0;
    }
    """

    hunger: reactive[float] = reactive(0.0)
    energy: reactive[float] = reactive(0.0)
    comfort: reactive[float] = reactive(0.0)
    curiosity: reactive[float] = reactive(0.0)
    social: reactive[float] = reactive(0.0)

    def compose(self) -> ComposeResult:
        yield Label("Needs", classes="panel-header")
        yield StatBar("Hunger", self.hunger, css_class="bar-hunger", id="bar-hunger")
        yield StatBar("Energy", self.energy, css_class="bar-energy", id="bar-energy")
        yield StatBar(
            "Comfort", self.comfort, css_class="bar-comfort", id="bar-comfort"
        )
        yield StatBar(
            "Curiosity", self.curiosity, css_class="bar-curiosity", id="bar-curiosity"
        )
        yield StatBar("Social", self.social, css_class="bar-social", id="bar-social")

    def update_needs(
        self,
        hunger: float,
        energy: float,
        comfort: float,
        curiosity: float,
        social: float,
    ) -> None:
        self.hunger = hunger
        self.energy = energy
        self.comfort = comfort
        self.curiosity = curiosity
        self.social = social
        try:
            self.query_one("#bar-hunger", StatBar).value = hunger
            self.query_one("#bar-energy", StatBar).value = energy
            self.query_one("#bar-comfort", StatBar).value = comfort
            self.query_one("#bar-curiosity", StatBar).value = curiosity
            self.query_one("#bar-social", StatBar).value = social
        except Exception:
            pass
