"""
Elephate CLI - Interactieve sessie

Start een interactieve chat-achtige sessie waar je commands kunt uitvoeren
zoals /calc, /help, /exit.
"""

from pathlib import Path
from typing import Optional

from prompt_toolkit import PromptSession
from prompt_toolkit.completion import WordCompleter
from prompt_toolkit.history import InMemoryHistory
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
from rich.console import Console
from rich.panel import Panel
from rich.text import Text

from . import __version__
from .parser import scan_directory, DocumentType
from .mock_data import get_mock_results, get_mock_token_usage, CATEGORIES
from .output import (
    print_files_found,
    simulate_processing,
    print_results_table,
    print_mock_warning,
    print_token_usage,
    print_export_info,
    print_error,
    print_success,
    print_info,
    console,
    ELEPHATE_BLUE,
)
from .export import export_json, export_csv, get_export_summary
from .auth import (
    get_credentials,
    save_credentials,
    clear_credentials,
    redeem_access_code,
    start_device_flow,
    poll_device_flow,
    open_browser_for_auth,
    is_authenticated,
    get_config_dir,
)


# ASCII Art voor ELEPHATE.AI - Windows-compatible
ASCII_ART = r"""
  _____ _     _____ ____  _   _    _  _____ _____      _    ___
 | ____| |   | ____|  _ \| | | |  / \|_   _| ____|    / \  |_ _|
 |  _| | |   |  _| | |_) | |_| | / _ \ | | |  _|     / _ \  | |
 | |___| |___| |___|  __/|  _  |/ ___ \| | | |___   / ___ \ | |
 |_____|_____|_____|_|   |_| |_/_/   \_\_| |_____| /_/   \_\___|
"""

TAGLINE = "Snel & nauwkeurig"
VERSION_TEXT = f"Versie {__version__}"


def print_startup():
    """Print de startup ASCII art en informatie."""
    console.print()

    # ASCII Art in blauw
    art_text = Text(ASCII_ART)
    art_text.stylize(ELEPHATE_BLUE)
    console.print(art_text)

    # Tagline en versie
    console.print(f"[bold white]                    {TAGLINE}[/]")
    console.print(f"[dim]                        {VERSION_TEXT}[/]")
    console.print()
    console.print("[dim]Type /help voor beschikbare commands, /exit om af te sluiten[/]")
    console.print()


def print_session_help():
    """Print de help voor de interactieve sessie."""
    console.print()
    console.print("[bold]Beschikbare Commands:[/]")
    console.print()
    console.print("[bold dim]Authenticatie:[/]")
    console.print("  [cyan]/login[/]             Log in (toegangscode of Auth0)")
    console.print("  [cyan]/logout[/]            Log uit")
    console.print("  [cyan]/status[/]            Toon login status")
    console.print()
    console.print("[bold dim]Calculatie:[/]")
    console.print("  [cyan]/calc[/]              Start calculatie in huidige directory")
    console.print("  [cyan]/calc <pad>[/]        Start calculatie voor specifiek pad")
    console.print("  [cyan]/calc --fast[/]       Snelle modus (skip animaties)")
    console.print()
    console.print("[bold dim]Informatie:[/]")
    console.print("  [cyan]/categories[/]        Toon STABU categorieën")
    console.print("  [cyan]/version[/]           Toon versie informatie")
    console.print("  [cyan]/info[/]              Toon systeem informatie")
    console.print("  [cyan]/help[/]              Toon deze help")
    console.print()
    console.print("[bold dim]Sessie:[/]")
    console.print("  [cyan]/clear[/]             Wis het scherm")
    console.print("  [cyan]/exit[/]              Sluit de sessie")
    console.print("  [cyan]/quit[/]              Sluit de sessie")
    console.print()


def run_calc(args: str = ""):
    """Voer de calc command uit."""
    # Check authentication first
    if not is_authenticated():
        print_error("Je moet eerst inloggen om calculaties uit te voeren")
        console.print("[dim]Gebruik /login om in te loggen met een toegangscode of Auth0[/]")
        return

    # Parse arguments
    parts = args.split()
    fast = "--fast" in parts or "-f" in parts
    paths = [p for p in parts if not p.startswith("-")]

    # Default naar huidige directory
    if not paths:
        paths = ["."]

    # Valideer paden
    valid_paths = []
    for path in paths:
        p = Path(path)
        if not p.exists():
            print_error(f"Pad niet gevonden: {path}")
            continue
        valid_paths.append(str(p))

    if not valid_paths:
        print_error("Geen geldige paden opgegeven")
        return

    # Scan voor PDFs
    pdf_files = scan_directory(valid_paths, recursive=True)

    if not pdf_files:
        print_error("Geen PDF bestanden gevonden")
        print_info("Tip: Navigeer naar een directory met PDF bestanden")
        return

    # Toon gevonden bestanden
    print_files_found(pdf_files)

    # Simuleer verwerking
    delay = 0.01 if fast else 0.05
    stats = simulate_processing(pdf_files, delay=delay)

    # Genereer mock resultaten
    results = get_mock_results(
        num_docs=len(pdf_files),
        add_variation=True
    )

    # Toon resultaten
    print_results_table(results)

    # Toon token gebruik
    total_pages = sum(f.num_pages for f in pdf_files)
    token_usage = get_mock_token_usage(num_docs=len(pdf_files), num_pages=total_pages)
    print_token_usage(token_usage)

    print_mock_warning()

    # Export resultaten
    output_dir = "./elephate-output"
    json_path = export_json(results, output_dir)
    csv_paths = export_csv(results, f"{output_dir}/csv")
    all_files = get_export_summary(json_path, csv_paths)
    print_export_info(output_dir, all_files[:4])
    if len(all_files) > 4:
        print_info(f"...en {len(all_files) - 4} meer bestanden")

    print_success("Calculatie voltooid")


def show_categories():
    """Toon de STABU categorieën."""
    console.print("[bold]STABU Categorieën[/]")
    console.print()

    for cat in CATEGORIES:
        console.print(f"  [cyan]{cat.code}[/] {cat.name}")
        console.print(f"      [dim]{cat.full_name}[/]")
        console.print()


def show_version():
    """Toon versie informatie."""
    console.print(f"[bold]Elephate CLI[/] v{__version__}")
    console.print("[dim]Calculatie Copilot voor installatiebedrijven[/]")
    console.print()
    console.print("[yellow]Dit is een mockup versie - geen echte LLM integratie[/]")


def show_info():
    """Toon systeem informatie."""
    import platform

    console.print("[bold]Systeem Informatie[/]")
    console.print()
    console.print(f"  Elephate CLI:  v{__version__}")
    console.print(f"  Python:        {platform.python_version()}")
    console.print(f"  Platform:      {platform.system()} {platform.release()}")
    console.print()

    # Check dependencies
    console.print("[bold]Dependencies:[/]")

    deps = [
        ("typer", "typer"),
        ("rich", "rich"),
        ("pypdf", "pypdf"),
        ("pymupdf", "fitz"),
        ("prompt_toolkit", "prompt_toolkit"),
    ]

    for name, module in deps:
        try:
            mod = __import__(module)
            version = getattr(mod, "__version__", "?")
            console.print(f"  [green][OK][/] {name}: {version}")
        except ImportError:
            console.print(f"  [red][X][/] {name}: niet geinstalleerd")


def run_login():
    """Handle /login command with method selection."""
    if is_authenticated():
        creds = get_credentials()
        console.print(f"[yellow]Je bent al ingelogd als {creds.email or 'onbekend'}[/]")
        console.print("[dim]Gebruik /logout om uit te loggen[/]")
        return

    console.print("[bold]Login bij Elephate[/]")
    console.print()
    console.print("  [cyan]1[/] Toegangscode")
    console.print("  [cyan]2[/] Auth0 (browser)")
    console.print()

    try:
        choice = console.input("[dim]Kies methode (1/2): [/]").strip()

        if choice == "1":
            _login_with_code()
        elif choice == "2":
            _login_with_auth0()
        else:
            print_error("Ongeldige keuze. Kies 1 of 2.")
    except KeyboardInterrupt:
        console.print()
        print_info("Login geannuleerd")


def _login_with_code():
    """Login met toegangscode."""
    console.print()
    console.print("[dim]Vraag een toegangscode aan via calc.elephate.ai[/]")

    try:
        access_code = console.input("[cyan]Toegangscode: [/]").strip()

        if not access_code:
            print_error("Geen toegangscode opgegeven")
            return

        console.print("[dim]Verifiëren...[/]")
        success, message, credentials = redeem_access_code(access_code)

        if success and credentials:
            save_credentials(credentials)
            print_success(f"Ingelogd! {message}")
            if credentials.email:
                console.print(f"[dim]Welkom, {credentials.email}[/]")
        else:
            print_error(message)

    except KeyboardInterrupt:
        console.print()
        print_info("Login geannuleerd")


def _login_with_auth0():
    """Login via Auth0 device flow."""
    console.print()
    console.print("[dim]Starting Auth0 device flow...[/]")

    success, message, device_data = start_device_flow()

    if not success:
        print_error(message)
        return

    # Show verification URL and code
    verification_uri = device_data.get("verification_uri_complete") or device_data.get("verification_uri")
    user_code = device_data.get("user_code", "")
    device_code = device_data.get("device_code", "")
    interval = device_data.get("interval", 5)

    console.print()
    console.print(f"[bold]Ga naar:[/] [cyan]{verification_uri}[/]")
    if user_code and not device_data.get("verification_uri_complete"):
        console.print(f"[bold]Code:[/] [yellow]{user_code}[/]")
    console.print()

    # Try to open browser
    if open_browser_for_auth(verification_uri):
        console.print("[dim]Browser geopend. Wachtend op autorisatie...[/]")
    else:
        console.print("[dim]Open de URL handmatig in je browser.[/]")

    console.print("[dim]Druk Ctrl+C om te annuleren[/]")
    console.print()

    # Poll for completion
    try:
        success, message, credentials = poll_device_flow(device_code, interval=interval)

        if success and credentials:
            save_credentials(credentials)
            print_success(f"Ingelogd via Auth0!")
            if credentials.email:
                console.print(f"[dim]Welkom, {credentials.email}[/]")
        else:
            print_error(message)

    except KeyboardInterrupt:
        console.print()
        print_info("Login geannuleerd")


def run_logout():
    """Handle /logout command."""
    if not is_authenticated():
        console.print("[yellow]Je bent niet ingelogd[/]")
        return

    creds = get_credentials()
    if clear_credentials():
        print_success("Uitgelogd")
        if creds and creds.email:
            console.print(f"[dim]Tot ziens, {creds.email}[/]")
    else:
        print_error("Kon niet uitloggen")


def show_status():
    """Show authentication status."""
    console.print("[bold]Status[/]")
    console.print()

    if is_authenticated():
        creds = get_credentials()
        console.print(f"  [green][OK][/] Ingelogd")
        if creds.email:
            console.print(f"  [dim]Email:[/] {creds.email}")
        console.print(f"  [dim]Methode:[/] {creds.auth_method}")
        console.print(f"  [dim]Config:[/] {get_config_dir()}")
    else:
        console.print(f"  [yellow][!][/] Niet ingelogd")
        console.print("[dim]Gebruik /login om in te loggen[/]")


def process_command(command: str) -> bool:
    """
    Verwerk een command.

    Returns:
        bool: True als de sessie moet doorgaan, False om te stoppen
    """
    command = command.strip()

    if not command:
        return True

    # Parse command en arguments
    if command.startswith("/"):
        parts = command[1:].split(maxsplit=1)
        cmd = parts[0].lower()
        args = parts[1] if len(parts) > 1 else ""
    else:
        # Behandel input zonder / als een bericht
        console.print(f"[dim]Onbekende input. Type /help voor commands.[/]")
        return True

    # Command handlers
    if cmd in ("exit", "quit", "q"):
        console.print("[dim]Tot ziens![/]")
        return False

    elif cmd == "help":
        print_session_help()

    elif cmd == "calc":
        run_calc(args)

    elif cmd == "categories":
        show_categories()

    elif cmd == "version":
        show_version()

    elif cmd == "info":
        show_info()

    elif cmd == "clear":
        console.clear()
        print_startup()

    elif cmd == "login":
        run_login()

    elif cmd == "logout":
        run_logout()

    elif cmd == "status":
        show_status()

    else:
        console.print(f"[red]Onbekend command: /{cmd}[/]")
        console.print("[dim]Type /help voor beschikbare commands[/]")

    return True


def start_session():
    """Start de interactieve sessie."""
    import sys

    # Check of we in een echte terminal draaien
    if not sys.stdin.isatty():
        console.print("[red]Error:[/] Interactieve modus vereist een terminal.")
        console.print("[dim]Gebruik 'elephate calc' voor niet-interactief gebruik.[/]")
        return

    # Print startup
    print_startup()

    # Command completer
    command_completer = WordCompleter(
        ["/calc", "/login", "/logout", "/status", "/help", "/exit", "/quit",
         "/version", "/info", "/categories", "/clear"],
        ignore_case=True
    )

    # Create session with history
    try:
        session = PromptSession(
            history=InMemoryHistory(),
            auto_suggest=AutoSuggestFromHistory(),
            completer=command_completer,
        )
    except Exception as e:
        console.print(f"[red]Error:[/] Kon interactieve sessie niet starten: {e}")
        console.print("[dim]Gebruik 'elephate calc' voor niet-interactief gebruik.[/]")
        return

    # Main loop
    running = True
    while running:
        try:
            # Prompt met Elephate styling
            user_input = session.prompt("elephate> ")
            running = process_command(user_input)

        except KeyboardInterrupt:
            # Ctrl+C - vraag bevestiging
            console.print()
            console.print("[dim]Druk Ctrl+C nogmaals om af te sluiten, of type een command[/]")
            try:
                user_input = session.prompt("elephate> ")
                running = process_command(user_input)
            except KeyboardInterrupt:
                console.print()
                console.print("[dim]Tot ziens![/]")
                running = False
            except EOFError:
                console.print()
                console.print("[dim]Tot ziens![/]")
                running = False

        except EOFError:
            # Ctrl+D - exit
            console.print()
            console.print("[dim]Tot ziens![/]")
            running = False
