"""Rich-based terminal display."""

from __future__ import annotations

import colorsys
import io
import sys

from tsumugi import __version__

from rich.console import Console
from rich.live import Live
from rich.markdown import Markdown
from rich.panel import Panel
from rich.rule import Rule
from rich.text import Text



def _make_console() -> Console:
    """Create a Rich Console with proper UTF-8 support on Windows."""
    if sys.platform == "win32" and hasattr(sys.stdout, "reconfigure"):
        sys.stdout.reconfigure(encoding="utf-8", errors="replace")
        if hasattr(sys.stderr, "reconfigure"):
            sys.stderr.reconfigure(encoding="utf-8", errors="replace")
    return Console(legacy_windows=False)


console = _make_console()


# ---------------------------------------------------------------------------
# Logo (ANSI Shadow style)
# ---------------------------------------------------------------------------

_LOGO_LINES = [
    "████████╗███████╗██╗   ██╗███╗   ███╗██╗   ██╗ ██████╗ ██╗",
    "╚══██╔══╝██╔════╝██║   ██║████╗ ████║██║   ██║██╔════╝ ██║",
    "   ██║   ███████╗██║   ██║██╔████╔██║██║   ██║██║  ███╗██║",
    "   ██║   ╚════██║██║   ██║██║╚██╔╝██║██║   ██║██║   ██║██║",
    "   ██║   ███████║╚██████╔╝██║ ╚═╝ ██║╚██████╔╝╚██████╔╝██║",
    "   ╚═╝   ╚══════╝ ╚═════╝ ╚═╝     ╚═╝ ╚═════╝  ╚═════╝ ╚═╝",
]


def _rainbow_logo() -> list[Text]:
    """Build the logo with rainbow gradient coloring."""
    max_len = max(len(line) for line in _LOGO_LINES)
    result = []
    for line in _LOGO_LINES:
        text = Text()
        for i, ch in enumerate(line):
            if ch == " ":
                text.append(" ")
            else:
                hue = i / max_len
                r, g, b = colorsys.hsv_to_rgb(hue, 1.0, 1.0)
                color = f"#{int(r*255):02x}{int(g*255):02x}{int(b*255):02x}"
                text.append(ch, style=f"bold {color}")
        result.append(text)
    return result


# ---------------------------------------------------------------------------
# Welcome screen
# ---------------------------------------------------------------------------

def print_welcome(
    *,
    provider: str,
    model: str,
    working_dir: str,
    tool_names: list[str],
    instructions_count: int,
    has_memory: bool = False,
) -> None:
    """Print the startup screen with logo and system info."""
    console.print()
    for line in _rainbow_logo():
        console.print(line)
    console.print()
    console.print(
        f"  [bold bright_cyan]AI Coding Agent[/bold bright_cyan] [dim]v{__version__}[/dim]"
    )
    console.print()
    console.print(Rule(style="bright_cyan"))
    console.print()

    # System info
    console.print(f"  [green]●[/green] [bold]Model[/bold]       {model}")
    console.print(f"  [cyan]●[/cyan] [bold]Provider[/bold]    {provider}")
    console.print(
        f"  [yellow]●[/yellow] [bold]Tools[/bold]       {', '.join(tool_names)}"
    )
    console.print(f"  [blue]●[/blue] [bold]CWD[/bold]         {working_dir}")
    if instructions_count:
        console.print(
            f"  [bright_cyan]●[/bright_cyan] [bold]TSUMUGI.md[/bold]  {instructions_count} file(s) loaded"
        )
    if has_memory:
        console.print(
            f"  [magenta]●[/magenta] [bold]MEMORY.md[/bold]   loaded"
        )
    console.print()
    console.print(Rule(style="bright_cyan"))
    console.print()
    console.print("  [dim]Ctrl+C で中断 • exit で終了[/dim]")
    console.print()


# ---------------------------------------------------------------------------
# Info / error
# ---------------------------------------------------------------------------

def print_error(message: str) -> None:
    """Print an error message."""
    console.print(f"[bold red]Error:[/bold red] {message}")


def print_info(message: str) -> None:
    """Print an info message."""
    console.print(f"[dim]{message}[/dim]")


# ---------------------------------------------------------------------------
# Markdown streaming (Rich Live)
# ---------------------------------------------------------------------------

class MarkdownStreamer:
    """Streams text and renders as Markdown using Rich Live."""

    def __init__(self) -> None:
        self._buffer = ""
        self._live: Live | None = None

    def start(self) -> None:
        """Begin streaming Markdown output."""
        self._buffer = ""
        self._live = Live(
            "",
            console=console,
            auto_refresh=True,
            refresh_per_second=8,
            vertical_overflow="visible",
        )
        self._live.start()

    def feed(self, delta: str) -> None:
        """Append a text delta and re-render."""
        self._buffer += delta
        if self._live:
            self._live.update(Markdown(self._buffer))

    def stop(self) -> str:
        """Stop streaming and return the accumulated text."""
        if self._live:
            if self._buffer:
                self._live.update(Markdown(self._buffer))
            self._live.stop()
            self._live = None
        text = self._buffer
        self._buffer = ""
        return text

    @property
    def text(self) -> str:
        return self._buffer


# ---------------------------------------------------------------------------
# Spinner / status
# ---------------------------------------------------------------------------

def create_thinking_status(message: str = "つむぎが考え中...") -> Live:
    """Create a spinner for thinking/waiting."""
    from rich.spinner import Spinner
    return Live(
        Spinner("dots", text=f"[bright_cyan]{message}[/bright_cyan]"),
        console=console,
        refresh_per_second=10,
        transient=True,
    )


def create_tool_status(tool_name: str) -> Live:
    """Create a spinner for tool execution."""
    from rich.spinner import Spinner
    return Live(
        Spinner("dots", text=f"[yellow]{tool_name} を実行中...[/yellow]"),
        console=console,
        refresh_per_second=10,
        transient=True,
    )


# ---------------------------------------------------------------------------
# Tool call / result display
# ---------------------------------------------------------------------------

def print_tool_call(name: str, args_summary: str) -> None:
    """Show that a tool is being called."""
    console.print(
        Panel(
            f"[bold cyan]{name}[/bold cyan]\n[dim]{args_summary}[/dim]",
            title="[yellow]Tool Call[/yellow]",
            border_style="yellow",
            expand=False,
        )
    )


def print_tool_result(result: str, is_error: bool = False) -> None:
    """Show tool execution result."""
    style = "red" if is_error else "green"
    title = "[red]Error[/red]" if is_error else "[green]Result[/green]"
    # Truncate long results
    display_text = result if len(result) <= 2000 else result[:2000] + "\n... (truncated)"
    console.print(
        Panel(
            display_text,
            title=title,
            border_style=style,
            expand=False,
        )
    )


# ---------------------------------------------------------------------------
# Token usage
# ---------------------------------------------------------------------------

def print_usage(input_tokens: int, output_tokens: int) -> None:
    """Display token usage for a turn."""
    total = input_tokens + output_tokens
    if total == 0:
        return
    console.print(
        f"[dim]tokens: {input_tokens:,} in / {output_tokens:,} out"
        f" ({total:,} total)[/dim]"
    )


# ---------------------------------------------------------------------------
# Permission request
# ---------------------------------------------------------------------------

def print_permission_request(
    tool_name: str, args_summary: str
) -> None:
    """Display permission request panel."""
    console.print(
        Panel(
            f"[bold]{tool_name}[/bold]\n{args_summary}",
            title="[yellow]Permission Required[/yellow]",
            border_style="yellow",
            expand=False,
        )
    )
