"""Message widgets for the conversation screen.

UserMessage — right-aligned observer message.
CreatureMessage — left-aligned creature response with typewriter effect.
EmotionShift — compact emotion indicator.
BondImpactDisplay — shows bond dimension changes.
"""

from __future__ import annotations

import asyncio

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

from sibilance.api.types import BondImpact, EmotionBrief


class UserMessage(Widget):
    """A message sent by the observer (user)."""

    DEFAULT_CSS = """
    UserMessage {
        height: auto;
        padding: 0 2 1 6;
    }
    UserMessage .user-label {
        color: $text-muted;
        text-style: italic;
    }
    UserMessage .user-text {
        color: $foreground;
        text-align: right;
    }
    """

    def __init__(self, text: str, **kwargs: object) -> None:
        super().__init__(**kwargs)
        self._text = text

    def compose(self) -> ComposeResult:
        yield Label("You", classes="user-label")
        yield Static(self._text, classes="user-text")


class CreatureMessage(Widget):
    """A response from the creature, with optional typewriter effect."""

    DEFAULT_CSS = """
    CreatureMessage {
        height: auto;
        padding: 0 6 1 2;
    }
    CreatureMessage .creature-label {
        color: $primary;
        text-style: bold;
    }
    CreatureMessage .creature-text {
        color: $foreground;
    }
    """

    def __init__(
        self,
        creature_name: str,
        text: str,
        *,
        typewriter: bool = True,
        **kwargs: object,
    ) -> None:
        super().__init__(**kwargs)
        self._creature_name = creature_name
        self._text = text
        self._typewriter = typewriter

    def compose(self) -> ComposeResult:
        yield Label(self._creature_name, classes="creature-label")
        # Start empty if typewriter, full text otherwise
        initial = "" if self._typewriter else self._text
        yield Static(initial, classes="creature-text", id="msg-body")

    async def on_mount(self) -> None:
        if self._typewriter and self._text:
            self.run_worker(self._typewrite(), name="typewrite")

    async def _typewrite(self) -> None:
        """Reveal text character by character."""
        body = self.query_one("#msg-body", Static)
        buf = ""
        for ch in self._text:
            buf += ch
            body.update(buf)
            await asyncio.sleep(0.025)  # 25ms per char, matching CLI


class EmotionShift(Widget):
    """Compact emotion indicator shown after creature response."""

    DEFAULT_CSS = """
    EmotionShift {
        height: 1;
        padding: 0 2 0 2;
    }
    EmotionShift .emotion-text {
        color: $primary;
        text-style: italic;
    }
    """

    def __init__(self, emotion: EmotionBrief, **kwargs: object) -> None:
        super().__init__(**kwargs)
        self._emotion = emotion

    def compose(self) -> ComposeResult:
        intensity_bar = "●" * max(1, round(self._emotion.intensity * 5))
        yield Label(
            f"({self._emotion.primary}) {intensity_bar}",
            classes="emotion-text",
        )


class BondImpactDisplay(Widget):
    """Shows bond dimension changes after an interaction."""

    DEFAULT_CSS = """
    BondImpactDisplay {
        height: auto;
        padding: 0 2 0 2;
    }
    BondImpactDisplay.no-impact {
        display: none;
    }
    BondImpactDisplay .bond-text {
        color: #4ecdc4;
    }
    """

    def __init__(self, impact: BondImpact, **kwargs: object) -> None:
        super().__init__(**kwargs)
        self._impact = impact

    def compose(self) -> ComposeResult:
        total = (
            self._impact.trust
            + self._impact.understanding
            + self._impact.influence
            + self._impact.resonance
        )
        if total <= 0.02:
            self.add_class("no-impact")
            return

        parts: list[str] = []
        for name, val in [
            ("trust", self._impact.trust),
            ("understanding", self._impact.understanding),
            ("influence", self._impact.influence),
            ("resonance", self._impact.resonance),
        ]:
            if val > 0:
                parts.append(f"{name} +{val * 100:.1f}%")

        if parts:
            yield Label(
                f"Bond: {', '.join(parts)}",
                classes="bond-text",
            )
        else:
            self.add_class("no-impact")


class SystemMessage(Widget):
    """A system/status message in the chat (e.g. "Thinking...", action results)."""

    DEFAULT_CSS = """
    SystemMessage {
        height: auto;
        padding: 0 2 0 2;
    }
    SystemMessage .system-text {
        color: $text-muted;
        text-style: italic;
    }
    """

    def __init__(self, text: str, **kwargs: object) -> None:
        super().__init__(**kwargs)
        self._text = text

    def compose(self) -> ComposeResult:
        yield Label(self._text, classes="system-text")
