"""Dashboard screen — the main view of the Sibilance TUI.

Layout (3-column grid):
  ┌────────────┬────────────┬────────────┐
  │  Creature  │  World     │  Events    │
  │  Display   │  Clock     │  Log       │
  │            ├────────────┤            │
  │            │  Bond      │            │
  │            │  Panel     │            │
  │            ├────────────┤            │
  │            │  Needs     │            │
  │            │  Panel     │            │
  │            ├────────────┤            │
  │            │  Info      │            │
  └────────────┴────────────┴────────────┘
  ┌──────────────────────────────────────┐
  │  > Talk to your creature...          │
  └──────────────────────────────────────┘
"""

from __future__ import annotations

from textual.app import ComposeResult
from textual.containers import Container, Vertical
from textual.screen import Screen
from textual.widgets import Footer, Header, Input, Label

from sibilance.api.types import CreatureStatus, WorldState
from sibilance.widgets.connection_status import ConnectionStatus
from sibilance.widgets.creature_display import CreatureDisplay
from sibilance.widgets.event_log import EventLog
from sibilance.widgets.stat_bar import BondPanel, NeedsPanel
from sibilance.widgets.world_clock import WorldClock


class DashboardScreen(Screen):
    """Main dashboard showing creature, stats, and events."""

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

    #dashboard-body {
        layout: horizontal;
        height: 1fr;
    }

    #col-creature {
        width: 1fr;
        min-width: 24;
        border: solid $secondary;
        background: $surface;
    }

    #col-stats {
        width: 1fr;
        min-width: 24;
        layout: vertical;
    }

    #col-events {
        width: 1fr;
        min-width: 24;
    }

    #bond-panel {
        height: auto;
        border: solid $secondary;
        background: $surface;
    }

    #needs-panel {
        height: auto;
        border: solid $secondary;
        background: $surface;
    }

    #world-clock {
        height: auto;
        border: solid $secondary;
        background: $surface;
    }

    #info-panel {
        height: 1fr;
        border: solid $secondary;
        background: $surface;
        padding: 1 2;
    }

    #info-panel .info-header {
        color: $text;
        text-style: bold;
    }

    #info-panel .info-line {
        color: $text-muted;
    }

    #conn-status {
        dock: bottom;
        height: 1;
    }

    #talk-input {
        dock: bottom;
        height: 3;
        margin: 0 1;
    }
    """

    def compose(self) -> ComposeResult:
        yield Header(show_clock=True)
        with Container(id="dashboard-body"):
            # Left column — creature display
            with Container(id="col-creature"):
                yield CreatureDisplay(id="creature-display")

            # Middle column — stats
            with Vertical(id="col-stats"):
                yield WorldClock(id="world-clock")
                yield BondPanel(id="bond-panel")
                yield NeedsPanel(id="needs-panel")
                with Container(id="info-panel"):
                    yield Label("Info", classes="info-header")
                    yield Label("Life stage: —", classes="info-line", id="info-stage")
                    yield Label("Story arcs: —", classes="info-line", id="info-arcs")
                    yield Label("Territories: —", classes="info-line", id="info-territories")
                    yield ConnectionStatus(id="conn-status")

            # Right column — events
            with Container(id="col-events"):
                yield EventLog(id="event-log")

        yield Input(
            placeholder="Talk to your creature...",
            id="talk-input",
        )
        yield Footer()

    def on_mount(self) -> None:
        """Load initial creature data from app state."""
        self._sync_creature()
        # Sync connection status
        try:
            conn = self.query_one("#conn-status", ConnectionStatus)
            conn.connected = self.app.connected  # type: ignore[attr-defined]
        except Exception:
            pass
        # Load recent events (not included in CreatureStatus)
        self.run_worker(self._load_events(), name="load-events")
        # Load world state for clock
        self.run_worker(self._load_world_state(), name="load-world")

    def _sync_creature(self) -> None:
        """Sync widget state from the app's creature reactive."""
        creature: CreatureStatus | None = self.app.creature  # type: ignore[attr-defined]
        if creature is None:
            return

        # Creature display
        display = self.query_one("#creature-display", CreatureDisplay)
        emotion_primary = creature.emotion.primary if creature.emotion else ""
        display.update_from_status(
            name=creature.name,
            life_stage=creature.life_stage,
            emotion_primary=emotion_primary,
            location=creature.location,
        )

        # Bond panel
        if creature.bond:
            bond_panel = self.query_one("#bond-panel", BondPanel)
            bond_panel.update_bond(
                trust=creature.bond.trust,
                understanding=creature.bond.understanding,
                influence=creature.bond.influence,
                resonance=creature.bond.resonance,
            )

        # Needs panel
        if creature.needs:
            needs_panel = self.query_one("#needs-panel", NeedsPanel)
            needs_panel.update_needs(
                hunger=creature.needs.hunger,
                energy=creature.needs.energy,
                comfort=creature.needs.comfort,
                curiosity=creature.needs.curiosity,
                social=creature.needs.social,
            )

        # Info panel
        try:
            self.query_one("#info-stage", Label).update(
                f"Life stage: {creature.life_stage}"
            )
            arcs_count = len(creature.story_arcs)
            self.query_one("#info-arcs", Label).update(
                f"Story arcs: {arcs_count} active"
            )
            terr_count = len(creature.territories)
            self.query_one("#info-territories", Label).update(
                f"Territories: {terr_count}"
            )
        except Exception:
            pass

    async def on_input_submitted(self, event: Input.Submitted) -> None:
        """Handle talk input submission."""
        message = event.value.strip()
        if not message:
            return

        event.input.value = ""

        try:
            api = self.app.api  # type: ignore[attr-defined]
            result = await api.talk_to_creature(message)

            # Quick talk from dashboard — show as notification
            # Full conversation available on the Chat screen (C key)
            self.notify(
                f"{result.creature_name}: {result.response[:200]}",
                timeout=10,
            )

            # Refresh creature state after interaction
            self.app.run_worker(  # type: ignore[attr-defined]
                self.app._refresh_creature(),  # type: ignore[attr-defined]
                name="refresh",
                exclusive=True,
            )
        except Exception as exc:
            self.notify(f"Error: {exc}", severity="error", timeout=5)

    async def _load_events(self) -> None:
        """Fetch recent events from the look endpoint and populate the log."""
        try:
            api = self.app.api  # type: ignore[attr-defined]
            look = await api.look_at_creature()
            if look.recent_events:
                event_log = self.query_one("#event-log", EventLog)
                event_log.events = look.recent_events
        except Exception:
            pass

    async def _load_world_state(self) -> None:
        """Fetch world state and update the clock."""
        try:
            api = self.app.api  # type: ignore[attr-defined]
            world = await api.get_world_state()
            clock = self.query_one("#world-clock", WorldClock)
            clock.update_from_world(world)
        except Exception:
            pass

    def refresh_from_creature(self, creature: CreatureStatus) -> None:
        """Called when the app's creature state changes."""
        self._sync_creature()

    def refresh_from_world(self, world: WorldState) -> None:
        """Called when world state updates arrive via WebSocket."""
        try:
            clock = self.query_one("#world-clock", WorldClock)
            clock.update_from_world(world)
        except Exception:
            pass
