"""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.

Input strategy (v0.7.7 — raw key capture):
  Textual's Input widget does NOT work in web terminals (Hostinger,
  etc.) because it relies on terminal escape sequences that web
  terminals don't relay correctly. Instead:

  1. A Static widget displays the current input text + cursor
  2. All keystrokes are captured at the App level via on_key()
  3. The App maintains a simple text buffer and updates the display
  4. Enter submits, Backspace deletes, Escape clears

  This uses the same key event pathway as ctrl+c (which works), so
  it's guaranteed to function in any terminal Textual can render to.

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 RichLog, Static


class ChatPane(Widget):
    """Agent Johnny 5 chat interface with RichLog history + raw key 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-display {
        dock: bottom;
        height: 3;
        margin: 0 1;
        padding: 0 1;
        border: tall #444444;
        background: #1a1a2e;
    }
    """

    def compose(self) -> ComposeResult:
        header = Static(
            "[bold]Agent Johnny 5[/bold]",
            id="chat-header",
            markup=True,
        )
        header.can_focus = False
        yield header

        chat_log = RichLog(
            highlight=False,
            markup=False,  # we write Rich Text objects directly
            wrap=True,
            auto_scroll=True,
            max_lines=2000,
            id="chat-log",
        )
        chat_log.can_focus = False
        yield chat_log

        # Raw input display — NOT a Textual Input widget.
        # Keystrokes are captured at the App level via on_key()
        # and rendered here as plain text + cursor block.
        input_display = Static(
            "[bold cyan]› [/bold cyan][dim]Type a message...[/dim]",
            id="chat-input-display",
            markup=True,
        )
        input_display.can_focus = False
        yield input_display

    def update_input_display(self, text: str) -> None:
        """Update the input display with current buffer content."""
        display = self.query_one("#chat-input-display", Static)
        if text:
            # Escape Rich markup characters in the user's text
            safe_text = text.replace("[", "\\[")
            display.update(f"[bold cyan]› [/bold cyan]{safe_text}[reverse] [/reverse]")
        else:
            display.update(
                "[bold cyan]› [/bold cyan][dim]Type a message...[/dim]"
            )

    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)
