"""Right pane (40%) — persistent chat with Agent Johnny 5.

The chat history uses RichLog (NOT VerticalScroll + Static widgets).
RichLog is optimised for rapid text appending — O(1) per write.

Streaming strategy:
  RichLog doesn't support updating the last line in-place, so we
  DON'T stream token-by-token to it. Instead:
  1. show_typing() writes "Johnny 5 is thinking..." to the log
  2. The brain streams internally (no UI updates per token)
  3. add_agent_message() writes the final complete response
  The typing indicator scrolls away naturally — clean UX for a TUI.
"""

from rich.text import Text
from textual.app import ComposeResult
from textual.widget import Widget
from textual.widgets import Input, RichLog, Static

from ..messages import UserChatSubmit


class ChatPane(Widget):
    """Agent Johnny 5 chat interface with RichLog history + Input."""

    DEFAULT_CSS = """
    ChatPane {
        height: 100%;
        layout: vertical;
    }

    ChatPane #chat-header {
        height: 3;
        content-align: center middle;
        background: $boost;
        text-style: bold;
        border-bottom: heavy #444444;
    }

    ChatPane #chat-log {
        height: 1fr;
        scrollbar-size-vertical: 1;
        scrollbar-background: $surface;
        scrollbar-color: $accent;
    }

    ChatPane #chat-input {
        dock: bottom;
        height: 3;
        margin: 0 1;
        border: tall #444444;
    }
    """

    def compose(self) -> ComposeResult:
        yield Static(
            "[bold]Agent Johnny 5[/bold]",
            id="chat-header",
            markup=True,
        )
        yield RichLog(
            highlight=False,
            markup=False,  # we write Rich Text objects directly
            wrap=True,
            auto_scroll=True,
            max_lines=2000,
            id="chat-log",
        )
        yield Input(
            placeholder="Ask Johnny 5 anything...",
            id="chat-input",
        )

    def on_input_submitted(self, event: Input.Submitted) -> None:
        """Bubble the user's message up to the App as a UserChatSubmit."""
        text = event.value.strip()
        if text:
            self.post_message(UserChatSubmit(text))
            event.input.value = ""

    def add_user_message(self, text: str) -> None:
        """Write a user message to the chat log with green prefix."""
        log = self.query_one("#chat-log", RichLog)
        styled = Text()
        styled.append("You: ", style="bold green")
        styled.append(text)
        log.write(styled)

    def show_typing(self) -> None:
        """Show a typing indicator while the agent is thinking."""
        log = self.query_one("#chat-log", RichLog)
        styled = Text()
        styled.append("Johnny 5: ", style="bold dodger_blue")
        styled.append("thinking...", style="dim italic")
        log.write(styled)

    def add_agent_message(self, text: str) -> None:
        """Write the agent's final complete response to the chat log."""
        log = self.query_one("#chat-log", RichLog)
        # Multi-line responses: prefix first line, indent the rest
        lines = text.split("\n")
        for i, line in enumerate(lines):
            styled = Text()
            if i == 0:
                styled.append("Johnny 5: ", style="bold dodger_blue")
            else:
                styled.append("  ", style="")  # indent continuation
            styled.append(line)
            log.write(styled)

    def add_tool_indicator(self, tool_name: str, args: dict) -> None:
        """Show a tool-call indicator in the chat log."""
        log = self.query_one("#chat-log", RichLog)
        styled = Text()
        styled.append(f"  [Tool: {tool_name}] ", style="bold yellow")
        # Show args concisely
        args_str = str(args)
        if len(args_str) > 60:
            args_str = args_str[:57] + "..."
        styled.append(args_str, style="dim")
        log.write(styled)
