"""
neurocli tui — WOW-level cyberpunk TUI
Full-screen launch, centered logo, glowing input bar
"""
import os
import sys
import time
from rich.console import Console
from rich.panel import Panel
from rich.text import Text
from rich.table import Table
from rich.align import Align
from rich.rule import Rule
from rich.progress import Progress, SpinnerColumn, TextColumn
from rich.markdown import Markdown
from rich.padding import Padding
from rich import box
import difflib

console = Console()

C_PRIMARY = "bright_cyan"
C_ACCENT  = "bright_green"
C_WARN    = "bright_yellow"
C_ERROR   = "bright_red"
C_DIM     = "grey50"
C_TOOL    = "bright_magenta"
C_SUCCESS = "bright_green"
C_MODEL   = "bright_blue"
C_USER    = "bold bright_white"


def _w():
    try:
        return console.width or 60
    except Exception:
        return 60


def _clear():
    os.system("clear")


def _center(text: str, style: str = ""):
    w = _w()
    if style:
        console.print(Align.center(Text(text, style=style)))
    else:
        console.print(Align.center(text))


def _blank(n=1):
    for _ in range(n):
        console.print()


# ─── BIG LOGO (scales to terminal width) ─────────────────────────────────────

LOGO_WIDE = [
    ("███╗   ██╗", "bright_cyan"),
    ("█████╗  ██╗   ██╗", "bright_cyan"),
    ("██╔██╗ ██║█████╗  ██║   ██║", "cyan"),
    ("██║╚██╗██║██╔══╝  ██║   ██║", "cyan"),
    ("██║ ╚████║███████╗╚██████╔╝", "blue"),
    ("╚═╝  ╚═══╝╚══════╝ ╚═════╝ ", "blue"),
]

# Block-style letter art for each char — narrow safe
LOGO_LINES = [
    "  ███╗  ██╗███████╗██╗   ██╗██████╗  █████╗  ██████╗██╗     ██╗",
    "  ████╗ ██║██╔════╝██║   ██║██╔══██╗██╔══██╗██╔════╝██║     ██║",
    "  ██╔██╗██║█████╗  ██║   ██║██████╔╝██║  ██║██║     ██║     ██║",
    "  ██║╚████║██╔══╝  ██║   ██║██╔══██╗██║  ██║██║     ██║     ██║",
    "  ██║ ╚███║███████╗╚██████╔╝██║  ██║╚█████╔╝╚██████╗███████╗██║",
    "  ╚═╝  ╚══╝╚══════╝ ╚═════╝ ╚═╝  ╚═╝ ╚════╝  ╚═════╝╚══════╝╚═╝",
]

LOGO_NARROW = [
    " ┌─────────────────┐",
    " │  N E U R O C L I│",
    " └─────────────────┘",
]

TAGLINE = "AI · FREE · FAST · BRUTAL"

SUBTITLE = "your terminal. your agent. no limits."


def print_banner(project: str = "", session_id: int = 0, model: str = "", tier: str = ""):
    _clear()
    w = _w()

    _blank(2)

    # ── Logo ──
    if w >= 68:
        colors = ["bright_cyan", "bright_cyan", "cyan", "cyan", "blue", "blue"]
        for line, color in zip(LOGO_LINES, colors):
            console.print(Align.center(Text(line, style=color)))
    elif w >= 30:
        # Compact stylized name
        _blank(1)
        t = Text()
        t.append("  ╔╗╔ ", style="bright_cyan")
        t.append("EURO", style="cyan")
        t.append("CLI", style="bright_cyan")
        console.print(Align.center(t))
        t2 = Text()
        t2.append("N", style="bold bright_cyan")
        t2.append("EURO", style="bold cyan")
        t2.append("CLI", style="bold bright_cyan")
        console.print(Align.center(Text("━" * 12, style="grey30")))
        _blank(1)
    else:
        _center("NEUROCLI", "bold bright_cyan")

    _blank(1)

    # ── Tagline ──
    tag = Text(justify="center")
    parts = TAGLINE.split(" · ")
    styles = ["bright_cyan", "bright_green", "bright_yellow", "bright_red"]
    for i, part in enumerate(parts):
        if i > 0:
            tag.append("  ·  ", style="grey30")
        tag.append(part, style=f"bold {styles[i]}")
    console.print(Align.center(tag))

    _blank(1)

    # ── Subtitle ──
    console.print(Align.center(Text(SUBTITLE, style="italic grey50")))

    _blank(1)

    # ── Divider ──
    console.print(Rule(style="grey23"))

    _blank(1)

    # ── Session info bar ──
    if project:
        tier_styles = {
            "read-only":     ("🔒", "bright_red"),
            "write-no-exec": ("✏ ", "bright_yellow"),
            "full-auto":     ("⚡", "bright_green"),
        }
        tier_icon, tier_color = tier_styles.get(tier, ("✏ ", "bright_yellow"))

        info = Text(justify="center")
        info.append("📁 ", style="grey50")
        info.append(project, style="bold bright_cyan")
        info.append("   ", style="")
        info.append(f"#{session_id}", style="grey42")
        info.append("   ", style="")
        info.append(model or "auto", style="bright_blue")
        info.append("   ", style="")
        info.append(f"{tier_icon} {tier}", style=tier_color)
        console.print(Align.center(info))

        _blank(1)

    # ── Commands hint ──
    hint = Text(justify="center")
    cmds = ["/undo", "/stats", "/bounty", "/watch", "/commit", "/memory", "/quit"]
    for i, cmd in enumerate(cmds):
        if i > 0:
            hint.append("  ", style="")
        hint.append(cmd, style="grey35")
    console.print(Align.center(hint))

    _blank(1)
    console.print(Rule(style="grey15"))
    _blank(1)


def print_header(project: str, session_id: int, model: str, tier: str, dry_run: bool):
    # Called after banner — just show dry-run warning if needed
    if dry_run:
        console.print(Align.center(Text("◈  DRY-RUN MODE — no changes will be made", style="bold bright_yellow")))
        _blank(1)


def print_help():
    pass  # help is in the banner


def print_user_input(text: str):
    _blank(1)
    console.print(Panel(
        Text(text, style="bold white"),
        title=Text("▸ you", style="bold bright_cyan"),
        title_align="left",
        border_style="bright_cyan",
        box=box.ROUNDED,
        padding=(0, 2),
    ))
    _blank(1)


def print_tool_start(name: str, args: dict):
    icons = {
        "read_file":    "📖",
        "write_file":   "✏ ",
        "list_files":   "📂",
        "search_files": "🔍",
        "run_command":  "⚡",
        "git_commit":   "📦",
    }
    icon = icons.get(name, "⚙ ")
    line = Text()
    line.append(f"  {icon} ", style="")
    line.append(name, style="bold bright_magenta")
    for k, v in args.items():
        line.append(f"  {k}=", style="grey50")
        line.append(repr(v)[:45], style="bright_green")
    console.print(line)


def print_tool_result(name: str, result: dict):
    ok = result.get("ok", False)
    dry = result.get("dry_run", False)

    if not ok:
        console.print(Panel(
            Text(result.get("error", "unknown error"), style="bright_red"),
            border_style="red",
            box=box.ROUNDED,
            padding=(0, 1),
        ))
        return

    if dry:
        console.print(Text("  ◈ dry-run — no changes made", style="bright_yellow"))
        if result.get("diff"):
            _print_diff(result["diff"])
        return

    if name == "write_file":
        line = Text()
        line.append("  ✔ ", style="bright_green")
        line.append("wrote ", style="grey50")
        line.append(result.get("path", ""), style="bright_cyan")
        line.append(f"  ({result.get('lines', 0)} lines)", style="grey42")
        console.print(line)
        if result.get("diff") and result["diff"] != "(no changes)":
            _print_diff(result["diff"])

    elif name == "read_file":
        line = Text()
        line.append("  ✔ ", style="bright_green")
        line.append("read ", style="grey50")
        line.append(result.get("path", ""), style="bright_cyan")
        console.print(line)

    elif name == "run_command":
        rc = result.get("returncode", 0)
        line = Text()
        line.append("  ✔ " if rc == 0 else "  ✗ ", style="bright_green" if rc == 0 else "bright_red")
        line.append(f"exit {rc}", style="grey50")
        console.print(line)
        out = ((result.get("stdout") or "") + (result.get("stderr") or "")).strip()
        if out:
            console.print(Panel(
                Text(out[:500], style="grey70"),
                border_style="grey23",
                box=box.ROUNDED,
                padding=(0, 1),
            ))

    elif name == "git_commit":
        line = Text()
        line.append("  ✔ ", style="bright_green")
        line.append("committed  ", style="grey50")
        line.append(result.get("output", "").strip()[:60], style="bright_cyan")
        console.print(line)

    elif name == "list_files":
        console.print(Panel(
            Text(result.get("tree", ""), style="grey70"),
            title=Text("files", style="grey50"),
            title_align="left",
            border_style="grey23",
            box=box.ROUNDED,
            padding=(0, 1),
        ))

    elif name == "search_files":
        hits = result.get("results", [])
        console.print(Text(f"  ✔  found {len(hits)} match(es)", style="bright_green"))
        for h in hits[:6]:
            row = Text("    ")
            row.append(h["file"], style="bright_cyan")
            row.append(f":{h['line']}", style="grey50")
            row.append(f"  {h['text'][:50]}", style="grey70")
            console.print(row)


def print_ai_response(text: str, model_used: str):
    if not text.strip():
        return
    _blank(1)
    console.print(Panel(
        Markdown(text),
        title=Text(f"⚡ {model_used}", style="bright_blue"),
        title_align="right",
        border_style="grey30",
        box=box.ROUNDED,
        padding=(0, 2),
    ))
    _blank(1)


def _print_diff(diff_str: str):
    if not diff_str or diff_str == "(no changes)":
        return
    t = Text()
    for line in diff_str.splitlines()[:40]:
        if line.startswith("+") and not line.startswith("+++"):
            t.append(line + "\n", style="bright_green")
        elif line.startswith("-") and not line.startswith("---"):
            t.append(line + "\n", style="bright_red")
        elif line.startswith("@@"):
            t.append(line + "\n", style="bright_blue")
        else:
            t.append(line + "\n", style="grey50")
    console.print(Panel(
        t,
        title=Text("diff", style="grey50"),
        title_align="left",
        border_style="grey23",
        box=box.ROUNDED,
        padding=(0, 1),
    ))


def print_diff_panel(old: str, new: str, filename: str):
    diff = list(difflib.unified_diff(
        old.splitlines(keepends=True),
        new.splitlines(keepends=True),
        fromfile=f"a/{filename}",
        tofile=f"b/{filename}",
        lineterm=""
    ))
    if diff:
        _print_diff("".join(diff))


def print_error(msg: str):
    _blank(1)
    console.print(Panel(
        Text(str(msg), style="bright_red"),
        border_style="bright_red",
        box=box.ROUNDED,
        padding=(0, 1),
    ))
    _blank(1)


def print_success(msg: str):
    t = Text()
    t.append("  ✔  ", style="bright_green")
    t.append(str(msg), style="white")
    console.print(t)


def print_info(msg: str):
    console.print(Align.center(Text(str(msg), style="grey50")))


def spinner(msg: str):
    return Progress(
        SpinnerColumn(spinner_name="dots2", style="bright_cyan"),
        TextColumn(f"[grey50]{msg}[/]"),
        transient=True,
        console=console,
    )


def print_stats(stats: dict):
    _blank(1)
    console.print(Align.center(Text("━━━  📊  STATS  ━━━", style="bold bright_cyan")))
    _blank(1)

    rows = [
        ("⚡  AI requests",   str(stats.get("ai_requests", 0))),
        ("✏   Lines written", str(stats.get("lines_written", 0))),
        ("🔧  Commands run",  str(stats.get("commands_run", 0))),
        ("📦  Git commits",   str(stats.get("commits_made", 0))),
        ("🔍  Bugs found",    str(stats.get("bugs_found", 0))),
        ("💾  Sessions",      str(stats.get("sessions_total", 0))),
    ]

    t = Table(box=box.SIMPLE, show_header=False, padding=(0, 3))
    t.add_column(style="grey50", min_width=22)
    t.add_column(style="bold bright_cyan", justify="right", min_width=6)
    for label, val in rows:
        t.add_row(label, val)
    console.print(Align.center(t))

    models = stats.get("models_used", {})
    if models:
        _blank(1)
        console.print(Align.center(Text("models", style="grey35")))
        for m, count in sorted(models.items(), key=lambda x: -x[1]):
            bar = Text()
            bar.append(f"  {m:<26}", style="bright_blue")
            bar.append("█" * min(count, 16), style="bright_cyan")
            bar.append(f"  {count}", style="grey50")
            console.print(Align.center(bar))

    _blank(1)
    console.print(Rule(style="grey15"))
    _blank(1)


def print_memory(mem: dict):
    _blank(1)
    console.print(Align.center(Text("━━━  🧠  MEMORY  ━━━", style="bold bright_cyan")))
    _blank(1)

    if mem.get("facts"):
        console.print(Text("  facts", style="grey42"))
        for f in mem["facts"][-10:]:
            row = Text()
            row.append("  ·  ", style="bright_cyan")
            row.append(f"{f['key']}: ", style="grey50")
            row.append(f["value"], style="white")
            console.print(row)

    if mem.get("preferences"):
        _blank(1)
        console.print(Text("  preferences", style="grey42"))
        for k, v in mem["preferences"].items():
            row = Text()
            row.append("  ·  ", style="bright_cyan")
            row.append(f"{k}: ", style="grey50")
            row.append(v, style="white")
            console.print(row)

    if mem.get("past_bugs"):
        _blank(1)
        console.print(Text("  past fixes", style="grey42"))
        for b in mem["past_bugs"][-5:]:
            row = Text()
            row.append("  ·  ", style="bright_yellow")
            row.append(b["file"], style="grey50")
            row.append("  " + b["description"][:50], style="white")
            console.print(row)

    _blank(1)
    console.print(Rule(style="grey15"))
    _blank(1)
