"""World status screen.

Shows the current world state: time, weather, mood, active events.
"""

from __future__ import annotations

from textual.app import ComposeResult
from textual.containers import VerticalScroll
from textual.screen import Screen
from textual.widgets import Footer, Header, Label, Static

from sibilance.api.types import CreatureStatus, WorldState
from sibilance.widgets.world_clock import (
    PERIOD_COLORS,
    PERIOD_ICONS,
    SEASON_ICONS,
    WEATHER_ICONS,
)


def _mood_label(mood: float) -> tuple[str, str]:
    """Return (label, color) for a global mood value (-1 to 1)."""
    if mood > 0.3:
        return "warm", "#6bcb77"
    if mood < -0.3:
        return "tense", "#ff6b6b"
    return "neutral", "#ffd93d"


def _mood_bar(mood: float, width: int = 20) -> str:
    """Render a bipolar mood bar centered at 0."""
    center = width // 2
    norm = max(-1.0, min(1.0, mood))
    filled = round(abs(norm) * center)

    if norm >= 0:
        bar = "░" * center + "█" * filled + "░" * (center - filled)
    else:
        bar = "░" * (center - filled) + "█" * filled + "░" * center

    return bar


class WorldScreen(Screen):
    """View the current world state."""

    DEFAULT_CSS = """
    WorldScreen {
        layout: vertical;
    }

    #world-header {
        dock: top;
        height: 1;
        padding: 0 2;
        background: $surface;
        color: $primary;
        text-style: bold;
        border-bottom: solid $secondary;
    }

    #world-scroll {
        height: 1fr;
        background: $background;
        padding: 1 2;
        scrollbar-color: $secondary;
        scrollbar-color-hover: $text-muted;
        scrollbar-color-active: $primary;
    }
    """

    def compose(self) -> ComposeResult:
        yield Header(show_clock=True)
        yield Label("World", id="world-header")
        yield VerticalScroll(id="world-scroll")
        yield Footer()

    def on_mount(self) -> None:
        self.run_worker(self._load_world(), name="load-world")

    async def _load_world(self) -> None:
        try:
            api = self.app.api  # type: ignore[attr-defined]
            world = await api.get_world_state()
            self._render_world(world)
        except Exception as exc:
            self.notify(f"Error: {exc}", severity="error", timeout=5)

    def _render_world(self, world: WorldState) -> None:
        scroll = self.query_one("#world-scroll", VerticalScroll)
        scroll.remove_children()

        t = world.time
        h = str(t.hour).zfill(2)
        m = str(t.minute).zfill(2)
        period_icon = PERIOD_ICONS.get(t.period, "◷")
        period_color = PERIOD_COLORS.get(t.period, "#8888aa")
        season_icon = SEASON_ICONS.get(t.season, "")
        weather_icon = WEATHER_ICONS.get(world.weather, "")

        # Time
        scroll.mount(
            Static(
                f"[{period_color}]{period_icon} {h}:{m}[/]  "
                f"[#4a4a6a]{t.period} · {t.day_of_week} · Day {t.day}[/]",
                markup=True,
            )
        )

        # Weather + season
        weather_desc = world.weather_description or world.weather
        scroll.mount(
            Static(
                f"{weather_icon} [bold]{weather_desc}[/]  "
                f"[#4a4a6a]{season_icon} {t.season.capitalize()}[/]",
                markup=True,
            )
        )

        # Global mood
        mood_label, mood_color = _mood_label(world.global_mood)
        bar = _mood_bar(world.global_mood)
        scroll.mount(
            Static(
                f"\n[#8888aa]Global Mood:[/]  [{mood_color}]{bar}[/]  "
                f"[{mood_color}]{mood_label}[/]",
                markup=True,
            )
        )

        # Active events
        if world.active_events:
            scroll.mount(
                Static(
                    "\n[bold #8888aa]Active Events[/]",
                    markup=True,
                )
            )
            for evt in world.active_events:
                cue_str = ""
                if evt.emotional_cue:
                    cue_str = f"  [#7b68ee]({evt.emotional_cue})[/]"
                scroll.mount(
                    Static(
                        f"[#4ecdc4]· {evt.location_name}[/]{cue_str}\n"
                        f"  [#c8c8e0]{evt.description}[/]",
                        markup=True,
                    )
                )
        else:
            scroll.mount(
                Static(
                    "\n[#4a4a6a italic]No active events.[/]",
                    markup=True,
                )
            )

    def refresh_from_creature(self, creature: CreatureStatus) -> None:
        pass

    def refresh_from_world(self, world: WorldState) -> None:
        """Live-update when world state changes via WebSocket."""
        self._render_world(world)
