"""Welcome message and onboarding display for Maeris CLI."""

import os
import sys
import time
from pathlib import Path

import click

from ._core import cli


# ---------------------------------------------------------------------------
# Brand constants
# ---------------------------------------------------------------------------

_BRAND = "bright_cyan"
_BRAND2 = "cyan"
_BRAND_DIM = "dim cyan"
_SUCCESS = "green"
_WARN = "yellow"
_ACCENT = "bold yellow"
_DIM = "dim"

# Half-block ASCII logo — bold, modern, clearly reads MAERIS
_LOGO_L1 = "█▀▄▀█ ▄▀█ █▀▀ █▀█ █ █▀"
_LOGO_L2 = "█ ▀ █ █▀█ ██▄ █▀▄ █ ▄█"


def _get_version() -> str:
    try:
        from maeris_mcp import __version__
        return __version__
    except Exception:
        return "0.0.0"


def _animated() -> bool:
    """Return True when the terminal supports animation."""
    return sys.stdout.isatty()


def _pause(seconds: float) -> None:
    """Sleep only when running in an interactive terminal."""
    if _animated():
        time.sleep(seconds)


# ---------------------------------------------------------------------------
# Status detection
# ---------------------------------------------------------------------------

def _detect_status() -> list[tuple[bool, str]]:
    """Return a list of (ok, label) tuples for the setup checklist."""
    from ._utils import _repo_config_dir

    checks: list[tuple[bool, str]] = []

    mcp_json = Path.cwd() / ".mcp.json"
    checks.append((mcp_json.exists(), "MCP configured"))

    try:
        from maeris_mcp.auth.token_store import TokenStore
        ts = TokenStore(config_dir=_repo_config_dir())
        logged_in = ts.is_authenticated() and not ts.is_token_expired()
        email = ts.get_email() if logged_in else None
        auth_label = f"Logged in as {email}" if email else "Logged in"
        checks.append((logged_in, auth_label if logged_in else "Not logged in"))
    except Exception:
        checks.append((False, "Not logged in"))

    try:
        from maeris_mcp.auth.token_store import TokenStore
        ts = TokenStore(config_dir=_repo_config_dir())
        app_name = ts.get_app_name() if ts.is_authenticated() else None
        if app_name:
            checks.append((True, f"App: {app_name}"))
        else:
            checks.append((False, "No app selected"))
    except Exception:
        checks.append((False, "No app selected"))

    return checks


def _detect_first_prompt() -> str:
    """Suggest a contextual first prompt based on the project type."""
    cwd = Path.cwd()

    has_frontend = any((
        (cwd / "package.json").exists(),
        (cwd / "src" / "App.tsx").exists(),
        (cwd / "src" / "App.jsx").exists(),
        (cwd / "src" / "App.vue").exists(),
        (cwd / "pages").is_dir(),
        (cwd / "app").is_dir(),
    ))
    has_api = any((
        (cwd / "routes").is_dir(),
        (cwd / "api").is_dir(),
        (cwd / "controllers").is_dir(),
        (cwd / "endpoints").is_dir(),
        (cwd / "server.py").exists(),
        (cwd / "app.py").exists(),
        (cwd / "main.go").exists(),
    ))

    if has_frontend:
        return "generate UI tests for the login flow"
    elif has_api:
        return "extract all API endpoints from my project"
    else:
        return "scan my repo for security issues"


# ---------------------------------------------------------------------------
# Animated rendering
# ---------------------------------------------------------------------------

def _get_console():
    from rich.console import Console
    return Console(highlight=False)


def _render_logo(console) -> None:
    """Animate the logo line by line with a gradient effect."""
    version = _get_version()

    console.print()
    console.print(f"  [bold {_BRAND}]{_LOGO_L1}[/]")
    _pause(0.06)
    console.print(f"  [bold {_BRAND2}]{_LOGO_L2}[/]")
    _pause(0.12)
    console.print(f"  [{_DIM}]Test. Secure. Ship.[/]  [{_BRAND_DIM}]v{version}[/]")
    console.print()


def _render_status(console, extra: list[tuple[bool, str]] | None = None) -> None:
    """Animate status checks appearing one by one with a leading spinner."""
    all_checks = _detect_status() + (extra or [])

    # Brief spinner before revealing results
    if _animated():
        with console.status(f"  [{_DIM}]Checking setup...[/]", spinner="dots"):
            time.sleep(0.5)

    all_ok = True
    for ok, label in all_checks:
        _pause(0.1)
        if ok:
            console.print(f"  [bold {_SUCCESS}]✓[/] [{_SUCCESS}]{label}[/]")
        else:
            console.print(f"  [bold {_WARN}]✗[/] [{_WARN}]{label}[/]")
            all_ok = False

    if all_ok:
        _pause(0.15)
        console.print(f"\n  [bold {_SUCCESS}]Ready to go.[/]")

    console.print()


def _render_commands(console) -> None:
    """Render the quick start commands in a styled panel."""
    from rich.panel import Panel
    from rich.text import Text

    cmds = [
        ("maeris scan security",  "Scan for vulnerabilities"),
        ("maeris scan api",       "Extract API endpoints"),
        ("maeris test generate",  "Generate UI tests"),
        ("maeris ci",            "Full quality gate"),
        ("maeris --help",        "See all commands"),
    ]

    content = Text()
    for i, (cmd, desc) in enumerate(cmds):
        padding = " " * max(1, 26 - len(cmd))
        content.append(f"  {cmd}", style=f"bold {_BRAND2}")
        content.append(f"{padding}{desc}", style=_DIM)
        if i < len(cmds) - 1:
            content.append("\n")

    console.print(Panel(
        content,
        title=f"[bold {_BRAND}] Quick start [/]",
        title_align="left",
        border_style=_BRAND_DIM,
        padding=(1, 1),
    ))


def _render_try_prompt(console) -> None:
    """Render the prompt suggestion with an optional typing animation."""
    from rich.live import Live
    from rich.text import Text

    prompt = _detect_first_prompt()

    console.print()

    if _animated():
        typed = ""
        with Live(Text("  Try: \"", style=_DIM), console=console, refresh_per_second=60) as live:
            for char in prompt:
                typed += char
                line = Text()
                line.append("  Try: ", style=_DIM)
                line.append(f'"{typed}', style=_ACCENT)
                live.update(line)
                time.sleep(0.025)

            final = Text()
            final.append("  Try: ", style=_DIM)
            final.append(f'"{prompt}"', style=_ACCENT)
            live.update(final)
    else:
        console.print(f'  [{_DIM}]Try:[/] [{_ACCENT}]"{prompt}"[/]')

    console.print()


def _render_next_steps(console, steps: list[tuple[str, str]]) -> None:
    """Render next steps in a yellow-bordered panel to draw attention."""
    if not steps:
        return

    from rich.panel import Panel
    from rich.text import Text

    content = Text()
    for i, (title, detail) in enumerate(steps):
        content.append(f"  {i + 1}. ", style="bold white")
        content.append(title, style=f"bold {_BRAND}")
        content.append(f"\n     {detail}", style=_DIM)
        if i < len(steps) - 1:
            content.append("\n\n")

    console.print(Panel(
        content,
        title=f"[bold {_WARN}] Next steps [/]",
        title_align="left",
        border_style=_WARN,
        padding=(1, 1),
    ))


def _render_support(console, portal_url: str | None = None) -> None:
    """Render compact support links."""
    from maeris_mcp.config import ENV as _ENV
    from rich.text import Text

    portal = portal_url or _ENV.app_url

    line = Text()
    line.append("  Docs ", style=_DIM)
    line.append("https://maeris.io/docs", style=f"{_BRAND2} underline")
    line.append("    ", style=_DIM)
    line.append("Portal ", style=_DIM)
    line.append(portal, style=f"{_BRAND2} underline")

    console.print()
    console.print(line)
    console.print()


# ---------------------------------------------------------------------------
# Generic welcome (external LLM mode)
# ---------------------------------------------------------------------------

def _show_welcome() -> None:
    """Print the Maeris welcome screen with animated logo, status, and next steps."""
    console = _get_console()

    _render_logo(console)
    _render_status(console)
    _render_commands(console)
    _render_try_prompt(console)

    # Next steps — only show what's incomplete
    incomplete: list[tuple[str, str]] = []
    for ok, label in _detect_status():
        if not ok and "Not logged in" in label:
            incomplete.append(("Log in to Maeris", "maeris auth login"))
        elif not ok and "No app" in label:
            incomplete.append(("Create your first app",
                               'maeris app create --name "My App" --url "https://myapp.com"'))
    _render_next_steps(console, incomplete)
    _render_support(console)


# ---------------------------------------------------------------------------
# Maeris AI mode welcome
# ---------------------------------------------------------------------------

def _show_maeris_ai_next_steps(listener_started: bool = False, has_credits: bool = False) -> None:
    """Post-setup next-steps screen shown after Maeris AI mode is enabled."""
    from maeris_mcp.config import ENV as _ENV
    portal_url = _ENV.app_url
    console = _get_console()

    _render_logo(console)
    console.print(f"  [{_DIM}]Hosted models — no personal API key needed.[/]")
    console.print()

    extra_status: list[tuple[bool, str]] = [
        (listener_started, "Listener running" if listener_started else "Listener not running"),
        (has_credits, "Credits available" if has_credits else f"No credits — add at {portal_url}"),
    ]
    _render_status(console, extra=extra_status)
    _render_commands(console)
    _render_try_prompt(console)

    incomplete: list[tuple[str, str]] = []
    if not has_credits:
        incomplete.append(("Buy credits", portal_url))
    if not listener_started:
        incomplete.append(("Start the listener", "maeris listen --background"))
    _render_next_steps(console, incomplete)
    _render_support(console, portal_url=portal_url)


# ---------------------------------------------------------------------------
# Command
# ---------------------------------------------------------------------------


@cli.command("welcome")
def welcome() -> None:
    """Show the Maeris welcome screen and feature overview."""
    _show_welcome()
