"""Retro ASCII title screen for the Cohort CLI."""

from __future__ import annotations

import io
import sys

# ANSI color codes -- degrade gracefully on dumb terminals
_RESET = "\033[0m"
_BOLD = "\033[1m"
_DIM = "\033[2m"
_CYAN = "\033[36m"
_YELLOW = "\033[33m"
_GREEN = "\033[32m"
_WHITE = "\033[97m"

# Brand terra cotta (#D97757) via 24-bit true-color escape
_TERRA = "\033[38;2;217;119;87m"
# Slightly lighter variant for accents
_TERRA_LIGHT = "\033[38;2;232;155;120m"

# fmt: off
_LOGO_UNICODE = [
    " ██████╗ ██████╗ ██╗  ██╗ ██████╗ ██████╗ ████████╗",
    "██╔════╝██╔═══██╗██║  ██║██╔═══██╗██╔══██╗╚══██╔══╝",
    "██║     ██║   ██║███████║██║   ██║██████╔╝   ██║   ",
    "██║     ██║   ██║██╔══██║██║   ██║██╔══██╗   ██║   ",
    "╚██████╗╚██████╔╝██║  ██║╚██████╔╝██║  ██║   ██║   ",
    " ╚═════╝ ╚═════╝ ╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═╝   ╚═╝   ",
]

_LOGO_ASCII = [
    "  ____ ___  _   _  ___  ____ _____",
    " / ___/ _ \\| | | |/ _ \\|  _ \\_   _|",
    "| |  | | | | |_| | | | | |_) || |  ",
    "| |__| |_| |  _  | |_| |  _ < | |  ",
    " \\____\\___/|_| |_|\\___/|_| \\_\\|_|  ",
]
# fmt: on

_TAGLINE = "Multi-Agent Orchestration Framework"


def _supports_color() -> bool:
    """Check if the terminal likely supports ANSI colors."""
    if not hasattr(sys.stdout, "isatty") or not sys.stdout.isatty():
        return False
    if sys.platform == "win32":
        try:
            import ctypes
            kernel32 = ctypes.windll.kernel32  # type: ignore[attr-defined]
            handle = kernel32.GetStdHandle(-11)
            mode = ctypes.c_ulong()
            kernel32.GetConsoleMode(handle, ctypes.byref(mode))
            kernel32.SetConsoleMode(handle, mode.value | 4)
            return True
        except Exception:
            return False
    return True


def _ensure_utf8() -> None:
    """Reconfigure stdout to UTF-8 on Windows if possible.

    Windows defaults to cp1252 / the active code page, which can't
    render block-drawing characters.  Modern Windows (10+) supports
    UTF-8 output fine -- the console just needs to be told.
    """
    if sys.platform != "win32":
        return
    if not isinstance(sys.stdout, io.TextIOWrapper):
        return
    enc = (sys.stdout.encoding or "").lower().replace("-", "")
    if enc in ("utf8", "utf16", "utf32", "utf8sig"):
        return  # already good
    try:
        # Set the console output code page to UTF-8 (65001)
        import ctypes
        ctypes.windll.kernel32.SetConsoleOutputCP(65001)  # type: ignore[attr-defined]
        # Reconfigure the stream in-place
        sys.stdout.reconfigure(encoding="utf-8")  # type: ignore[attr-defined]
        sys.stderr.reconfigure(encoding="utf-8")  # type: ignore[union-attr,attr-defined]
    except Exception:
        pass  # fall through -- _supports_unicode will pick the ASCII path


def _supports_unicode() -> bool:
    """Check if stdout can handle Unicode box-drawing characters."""
    if isinstance(sys.stdout, io.TextIOWrapper):
        enc = (sys.stdout.encoding or "").lower().replace("-", "")
        return enc in ("utf8", "utf16", "utf32", "utf8sig")
    try:
        "\u2588".encode(sys.stdout.encoding or "ascii")
        return True
    except (UnicodeEncodeError, LookupError):
        return False


def _c(code: str, text: str, *, color: bool = True) -> str:
    """Wrap *text* in an ANSI escape if color is enabled."""
    if not color:
        return text
    return f"{code}{text}{_RESET}"


def print_banner(*, version: str = "", color: bool | None = None) -> None:
    """Print the retro Cohort title screen.

    Parameters
    ----------
    version:
        Optional version string (e.g. ``"0.4.1"``).
    color:
        Force color on/off.  ``None`` = auto-detect.
    """
    _ensure_utf8()
    use_color = color if color is not None else _supports_color()
    use_unicode = _supports_unicode()

    logo = _LOGO_UNICODE if use_unicode else _LOGO_ASCII
    logo_width = max(len(line) for line in logo)
    # Help text body is ~75 chars; center logo + border over it
    content_width = 75
    width = max(logo_width, content_width)
    border_char = "═" if use_unicode else "="
    border = border_char * width

    print()
    print(_c(_TERRA + _BOLD, border, color=use_color))
    for line in logo:
        pad = max(0, (width - len(line)) // 2)
        print(_c(_TERRA + _BOLD, " " * pad + line, color=use_color))
    print(_c(_TERRA + _BOLD, border, color=use_color))

    # Tagline centered under the logo
    pad = max(0, (width - len(_TAGLINE)) // 2)
    tagline = " " * pad + _TAGLINE
    print(_c(_TERRA_LIGHT, tagline, color=use_color))

    if version:
        ver_str = f"v{version}"
        vpad = max(0, (width - len(ver_str)) // 2)
        print(_c(_DIM, " " * vpad + ver_str, color=use_color))

    print()


def print_help(*, color: bool | None = None) -> None:
    """Print the styled help screen with grouped commands."""
    use_color = color if color is not None else _supports_color()

    def heading(text: str) -> str:
        return _c(_TERRA + _BOLD, text, color=use_color)

    def cmd(name: str) -> str:
        return _c(_TERRA_LIGHT, f"  {name:20s}", color=use_color)

    def dim(text: str) -> str:
        return _c(_DIM, text, color=use_color)

    print(heading("Two ways to use Cohort:"))
    print()
    print(dim("  MCP mode   Connect via Claude Code, Cursor, or any MCP client."))
    print(dim("             Run 'cohort setup' to configure, then restart your client."))
    print(dim("             All tools (discussions, channels, search) work through your LLM."))
    print()
    print(dim("  CLI mode   Run commands directly from the terminal."))
    print(dim("             Useful for scripting, CI, or working without an LLM client."))
    print(dim("             Same channels, agents, and scoring engine -- different interface."))
    print()

    print(heading("Usage:"))
    print(
        f"  {_c(_WHITE, 'cohort', color=use_color)}"
        f" {_c(_TERRA_LIGHT, '<command>', color=use_color)} [options]"
    )
    print()

    print(heading("Scoring Engine:"))
    print(f"{cmd('gate')}Should this agent respond?  SPEAK / SILENT decision")
    print(f"{cmd('next-speaker')}Rank all agents by relevance, pick the top N")
    print()

    print(heading("Discussions:"))
    print(f"{cmd('discuss')}Score agents and rank speaker order for a topic")
    print(dim("                      Uses the 5-dim scoring engine.  Includes channel history."))
    print(dim("                      You orchestrate: adopt each persona in scored order."))
    print(f"{cmd('roundtable')}Run a full multi-agent discussion locally (Ollama)")
    print(dim("                      Single LLM call, all personas, structured rounds."))
    print(dim("                      Pulls channel history as context, posts results back."))
    print()

    print(heading("Agents:"))
    print(f"{cmd('create-agent')}Register a new agent in the local store")
    print(f"{cmd('list-agents')}List all registered agents")
    print()

    print(heading("Channels:"))
    print(f"{cmd('say')}Post a message to a channel")
    print(f"{cmd('read')}Read recent messages from a channel")
    print(f"{cmd('search')}Search messages across all channels")
    print(f"{cmd('briefing')}Generate or view executive briefings")
    print()

    print(heading("Servers:"))
    print(f"{cmd('mcp')}Start the Cohort MCP server  (Claude, Cursor, etc.)")
    print(f"{cmd('mcp-local')}Start the local LLM server  (Ollama)")
    print()

    print(heading("Getting Started:"))
    print(f"{cmd('setup')}Interactive setup wizard  (hardware, model, feeds)")
    print(f"{cmd('tutorial')}Walk through the scoring engine step by step")
    print()

    print(heading("Maintenance:"))
    print(f"{cmd('reset')}Factory reset -- wipe runtime data to defaults")
    print()

    print(dim("  Run 'cohort <command> --help' for details on any command."))
    print(dim("  Docs: https://rwheeler007.github.io/cohort/"))
    print()
