"""Renderers for user and assistant chat messages."""

from __future__ import annotations

from rich.console import RenderableType
from rich.box import ROUNDED
from rich.markdown import Markdown
from rich.panel import Panel
from rich.text import Text

from clients.terminal.tui.themes import get_active_theme

from .base import ContentRenderer
from .markdown_content import ThemedMarkdownRenderable, _theme_aware_code_theme


def _hex_style(color) -> str:
    """Return a Rich-compatible hex style string from a Textual Color."""
    return color.hex


class UserMessageRenderer(ContentRenderer):
    """Render a user message bubble."""

    def accepts(self, msg: dict) -> bool:
        return msg.get("type") == "user_message"

    def render(self, msg: dict) -> RenderableType:
        theme = get_active_theme()
        text = msg.get("content", "")
        return Panel(
            Text(text, style=_hex_style(theme.text)),
            title="You",
            title_align="left",
            border_style=_hex_style(theme.user_bubble),
            box=ROUNDED,
        )


class AssistantMessageRenderer(ContentRenderer):
    """Render an assistant response as a panel with markdown content.

    The body is parsed as markdown (headings, lists, bold/italic, inline and
    fenced code blocks with theme-aware syntax highlighting) using the same
    themed renderer as the planning cards. Re-rendered on every stream delta
    so the formatting appears live as Navi streams.
    """

    def accepts(self, msg: dict) -> bool:
        return msg.get("type") == "assistant_message"

    def render(self, msg: dict) -> RenderableType:
        theme = get_active_theme()
        text = msg.get("content", "") or ""
        code_theme = _theme_aware_code_theme(theme.name)
        body = ThemedMarkdownRenderable(
            Markdown(text, code_theme=code_theme, inline_code_theme=code_theme),
            theme.name,
        )
        return Panel(
            body,
            title="Navi",
            title_align="left",
            border_style=_hex_style(theme.assistant_bubble),
            box=ROUNDED,
        )

    def render_plain(self, msg: dict) -> RenderableType:
        # In reading mode return the raw markdown text rather than unwrapping the
        # Panel's Markdown body: rich Markdown re-wraps fenced code blocks in
        # their own Panels, so the borders would leak back into a raw-terminal
        # copy. Raw markdown copies clean (fences stay as ```…``` text).
        theme = get_active_theme()
        return Text(msg.get("content", "") or "", style=_hex_style(theme.text))
