"""Rich terminal UI with ASCII art welcome screen and arrow-key navigation."""

from __future__ import annotations

import sys
from pathlib import Path
from typing import List, Optional, Tuple

import readchar
from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.text import Text

from .. import __version__
from ..engine.runner import Finding, ScanResult
from ..scanners.detector import Platform

console = Console()

# Match the web theme: --accent: #eeef20, --success: #22c55e,
# --warning: #eab308, --danger: #ef4444, --muted: #a1a1aa
_ACCENT = "#eeef20"

_SEVERITY_STYLES = {
    "FAIL": "bold #ef4444",
    "WARN": "bold #eab308",
    "INFO": "bold blue",
}

_SEVERITY_ICONS = {
    "FAIL": "\u2718",  # ✘
    "WARN": "\u26a0",  # ⚠
    "INFO": "\u2139",  # ℹ
}

# ---------------------------------------------------------------------------
# ASCII Art
# ---------------------------------------------------------------------------

_LOGO = r"""
[bold #eeef20]
     ██████╗ ███╗   ██╗ ██████╗███████╗ ██████╗██╗  ██╗███████╗ ██████╗██╗  ██╗
    ██╔═══██╗████╗  ██║██╔════╝██╔════╝██╔════╝██║  ██║██╔════╝██╔════╝██║ ██╔╝
    ██║   ██║██╔██╗ ██║██║     █████╗  ██║     ███████║█████╗  ██║     █████╔╝
    ██║   ██║██║╚██╗██║██║     ██╔══╝  ██║     ██╔══██║██╔══╝  ██║     ██╔═██╗
    ╚██████╔╝██║ ╚████║╚██████╗███████╗╚██████╗██║  ██║███████╗╚██████╗██║  ██╗
     ╚═════╝ ╚═╝  ╚═══╝ ╚═════╝╚══════╝ ╚═════╝╚═╝  ╚═╝╚══════╝ ╚═════╝╚═╝  ╚═╝
[/bold #eeef20]"""

_SHIELD = r"""[bold #eeef20]
               ╔══════════════════════════╗
               ║   ┌──────────────────┐   ║
               ║   │  [bold #22c55e]✓[/bold #22c55e] iOS    [bold #22c55e]✓[/bold #22c55e] Web  │   ║
               ║   │  [bold #22c55e]✓[/bold #22c55e] Android       │   ║
               ║   └──────────────────┘   ║
               ║      [bold white]v{version}[/bold white]             ║
               ╚══════════╦═══════════════╝
                          ║
                          ╩
[/bold #eeef20]"""

_TAGLINE = "[dim italic]  Ship with confidence. Catch compliance risks before the app stores do.[/dim italic]"

_DIVIDER = "[dim #eeef20]  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[/dim #eeef20]"


# ---------------------------------------------------------------------------
# Arrow-key menu selector
# ---------------------------------------------------------------------------

def arrow_select(
    title: str,
    options: List[Tuple[str, str]],
    *,
    icons: Optional[List[str]] = None,
) -> str:
    """Render an arrow-key navigable menu and return the selected value.

    Parameters
    ----------
    title:
        Heading text shown above the menu.
    options:
        List of (label, return_value) tuples.
    icons:
        Optional list of icon strings, one per option.

    Returns the ``return_value`` of the selected option.
    """
    selected = 0
    total = len(options)

    while True:
        # Build the menu text
        lines: List[str] = []
        for i, (label, _value) in enumerate(options):
            icon = icons[i] if icons else ""
            if i == selected:
                prefix = "[bold #eeef20]  \u276f [/bold #eeef20]"
                style_open, style_close = "[bold #eeef20]", "[/bold #eeef20]"
            else:
                prefix = "    "
                style_open, style_close = "[dim]", "[/dim]"
            line = f"{prefix}{style_open}{icon}  {label}{style_close}" if icon else f"{prefix}{style_open}{label}{style_close}"
            lines.append(line)

        menu_body = "\n".join(lines)
        hint = "\n[dim]  Use \u2191\u2193 arrows to navigate, Enter to select[/dim]"

        rendered = Panel(
            f"\n{menu_body}\n{hint}\n",
            title=f"[bold]{title}[/bold]",
            border_style="#eeef20",
            expand=False,
            padding=(0, 2),
        )

        console.clear()
        console.print(_DIVIDER)
        console.print()
        console.print(rendered)

        # Read a keypress
        key = readchar.readkey()

        if key == readchar.key.UP:
            selected = (selected - 1) % total
        elif key == readchar.key.DOWN:
            selected = (selected + 1) % total
        elif key in (readchar.key.ENTER, "\r", "\n"):
            console.clear()
            return options[selected][1]
        elif key in ("q", readchar.key.ESC):
            # ESC / q = pick last option (Exit)
            console.clear()
            return options[-1][1]


# ---------------------------------------------------------------------------
# Welcome + Menu Screens
# ---------------------------------------------------------------------------

def print_welcome() -> None:
    """Show the big ASCII art splash screen."""
    console.clear()
    console.print(_LOGO)
    console.print(_SHIELD.replace("{version}", __version__))
    console.print(_TAGLINE)
    console.print(_DIVIDER)
    console.print()
    console.print("[dim]  Press any key to continue...[/dim]")
    readchar.readkey()


def prompt_main_menu() -> str:
    """Arrow-key main menu. Returns: 'scan', 'login', 'status', or 'exit'."""
    return arrow_select(
        "Main Menu",
        [
            ("Scan a project",             "scan"),
            ("Login / Authenticate",       "login"),
            ("Check subscription status",  "status"),
            ("Exit",                       "exit"),
        ],
        icons=["\U0001f50d", "\U0001f511", "\U0001f4cb", "\U0001f44b"],
    )


def prompt_platform() -> str:
    """Arrow-key platform picker. Returns: 'auto', 'ios', 'android', or 'web'."""
    return arrow_select(
        "Select Platform",
        [
            ("Auto-detect",                                   "auto"),
            ("iOS  (SwiftUI, UIKit, Xcode)",                  "ios"),
            ("Android  (Gradle, Kotlin/Java)",                "android"),
            ("Web  (Next.js, React, Vue, Astro, Node)",       "web"),
        ],
        icons=["\U0001f916", "\U0001f34e", "\U0001f916", "\U0001f310"],
    )


def prompt_project_path() -> str:
    """Ask the user for the project directory to scan (text input)."""
    console.print()
    console.print(
        Panel(
            "\n  [bold]Enter the project path to scan[/bold]\n"
            "  [dim](press Enter for current directory)[/dim]\n",
            border_style="#eeef20",
            expand=False,
            padding=(0, 2),
        )
    )
    while True:
        path_str = console.input("  [bold #eeef20]\u276f[/bold #eeef20] ").strip()
        if not path_str:
            path_str = "."
        p = Path(path_str).expanduser().resolve()
        if p.is_dir():
            return str(p)
        console.print(f"  [bold #ef4444]Not a valid directory:[/bold #ef4444] {path_str}")


def prompt_post_scan(is_team: bool = False) -> str:
    """After scan results, let user choose next action."""
    options = [
        ("Browse findings interactively", "browse"),
    ]
    icons = ["\U0001f50e"]

    if is_team:
        options.append(("Export results (JSON / Text / SARIF)", "export"))
        icons.append("\U0001f4be")

    options.extend([
        ("Back to main menu", "menu"),
        ("Exit",              "exit"),
    ])
    icons.extend(["\u2190", "\U0001f44b"])

    return arrow_select("What next?", options, icons=icons)


def prompt_export_format() -> str:
    """Arrow-key export format picker."""
    return arrow_select(
        "Export Format",
        [
            ("JSON",  "json"),
            ("Text",  "text"),
            ("SARIF", "sarif"),
        ],
        icons=["\U0001f4c4", "\U0001f4dd", "\U0001f6e1"],
    )


def prompt_export_location() -> str:
    """Arrow-key save location picker. Returns a directory path."""
    home = Path.home()
    cwd = Path.cwd()

    options = [
        (f"Current directory  ({cwd.name}/)", str(cwd)),
        (f"Desktop  ({home / 'Desktop'})", str(home / "Desktop")),
        (f"Documents  ({home / 'Documents'})", str(home / "Documents")),
        (f"Downloads  ({home / 'Downloads'})", str(home / "Downloads")),
    ]

    # Only show directories that exist
    valid = [(label, val) for label, val in options if Path(val).is_dir()]

    return arrow_select(
        "Save Location",
        valid,
        icons=["\U0001f4c2"] * len(valid),
    )


# ---------------------------------------------------------------------------
# Scan Results Display
# ---------------------------------------------------------------------------

def print_header() -> None:
    header_art = r"""[bold #eeef20]
    ╔═══════════════════════════════════════════════════╗
    ║        [bold white]SCAN RESULTS[/bold white]                               ║
    ╚═══════════════════════════════════════════════════╝[/bold #eeef20]"""
    console.print(header_art)


def print_scan_result(result: ScanResult) -> None:
    """Display a complete scan result with summary and findings."""
    console.print()
    console.print(f"  [bold #eeef20]\u25c6[/bold #eeef20] Platform: [bold]{result.platform.value.upper()}[/bold] ({result.project_type})")
    console.print(f"  [bold #eeef20]\u25c6[/bold #eeef20] Scan Time: [bold]{result.scan_time_seconds:.1f}s[/bold]")
    console.print()

    # Summary box
    fail_bar = "\u2588" * max(result.fail_count, 0)
    warn_bar = "\u2588" * max(result.warn_count, 0)
    info_bar = "\u2588" * max(result.info_count, 0)

    summary_text = (
        f"  [bold #ef4444]FAIL  {result.fail_count:>3}  {fail_bar}[/bold #ef4444]\n"
        f"  [bold #eab308]WARN  {result.warn_count:>3}  {warn_bar}[/bold #eab308]\n"
        f"  [bold blue]INFO  {result.info_count:>3}  {info_bar}[/bold blue]"
    )
    console.print(
        Panel(summary_text, title="[bold]Summary[/bold]", border_style="#eeef20", expand=False, padding=(1, 2))
    )
    console.print()

    if not result.findings:
        console.print("  [bold #22c55e]\u2714 No compliance issues found! Ship it![/bold #22c55e]")
        return

    # Findings list
    severity_order = {"FAIL": 0, "WARN": 1, "INFO": 2}
    sorted_findings = sorted(result.findings, key=lambda f: severity_order.get(f.severity, 3))

    for finding in sorted_findings:
        _print_finding(finding)

    console.print()


def _print_finding(finding: Finding) -> None:
    style = _SEVERITY_STYLES.get(finding.severity, "")
    icon = _SEVERITY_ICONS.get(finding.severity, "")

    console.print(
        f"  [{style}]{icon} [{finding.severity}][/{style}] "
        f"[bold]{finding.rule_id}[/bold] {finding.message}"
    )
    console.print(f"          [dim]\u2514\u2500 Fix: {finding.fix}[/dim]")
    if finding.reference:
        console.print(f"          [dim]   Ref: {finding.reference}[/dim]")


def print_footer(results: List[ScanResult]) -> None:
    """Print final summary across all scanned platforms."""
    total_fail = sum(r.fail_count for r in results)
    total_warn = sum(r.warn_count for r in results)

    console.print()
    console.print(_DIVIDER)
    console.print()
    if total_fail > 0:
        platforms = {r.platform for r in results}
        if platforms == {Platform.WEB}:
            action = "Fix these before deploying to production."
        elif Platform.WEB not in platforms:
            action = "Fix these before submitting to app stores."
        else:
            action = "Fix these before shipping."
        console.print(
            f"  [bold #ef4444]\u2718 {total_fail} failure(s) found. {action}[/bold #ef4444]"
        )
    elif total_warn > 0:
        console.print(
            f"  [bold #eab308]\u26a0 {total_warn} warning(s) found. Review recommended.[/bold #eab308]"
        )
    else:
        console.print("  [bold #22c55e]\u2714 All checks passed! You're good to ship![/bold #22c55e]")
    console.print()
