"""
meshpi.config
=============
Interactive configuration wizard.
Creates/updates ~/.meshpi/config.env on the HOST machine.
"""

from __future__ import annotations

import getpass
from pathlib import Path

from rich.console import Console
from rich.panel import Panel
from rich.prompt import Confirm, Prompt

from .crypto import ensure_meshpi_dir

console = Console()

CONFIG_PATH = Path.home() / ".meshpi" / "config.env"

# List of (key, label, sensitive, default)
CONFIG_FIELDS = [
    # --- SSH user ---
    ("RPI_USER",        "Default Linux username",           False, "pi"),
    ("RPI_PASSWORD",    "Default Linux password",           True,  ""),
    # --- WiFi ---
    ("WIFI_SSID",       "WiFi network name (SSID)",         False, ""),
    ("WIFI_PASSWORD",   "WiFi password",                    True,  ""),
    ("WIFI_COUNTRY",    "WiFi country code (e.g. PL)",      False, "PL"),
    # --- Hostname ---
    ("RPI_HOSTNAME",    "Default hostname prefix",          False, "meshpi"),
    # --- SSH configuration ---
    ("SSH_PUBLIC_KEY",  "SSH public key (~/.ssh/id_rsa.pub)", False, ""),
    ("SSH_ENABLE",      "Enable SSH on client (yes/no)",    False, "yes"),
    ("SSH_PORT",        "SSH port",                         False, "22"),
    ("SSH_PASSWORD_AUTH", "SSH password authentication (yes/no)", False, "yes"),
    # --- Locale / timezone ---
    ("RPI_TIMEZONE",    "Timezone (e.g. Europe/Warsaw)",    False, "Europe/Warsaw"),
    ("RPI_LOCALE",      "Locale (e.g. pl_PL.UTF-8)",        False, "pl_PL.UTF-8"),
    ("RPI_KEYBOARD",    "Keyboard layout (e.g. pl)",        False, "pl"),
    # --- Hardware interfaces ---
    ("ENABLE_I2C",      "Enable I2C interface (yes/no)",    False, "no"),
    ("ENABLE_SPI",      "Enable SPI interface (yes/no)",    False, "no"),
    ("ENABLE_SERIAL",   "Enable serial console (yes/no)",   False, "no"),
    ("ENABLE_CAMERA",   "Enable camera interface (yes/no)", False, "no"),
    # --- Network ---
    ("STATIC_IP",       "Static IP address (empty for DHCP)", False, ""),
    ("GATEWAY",         "Gateway IP (for static IP)",       False, ""),
    ("DNS_SERVERS",     "DNS servers (comma-separated)",    False, "8.8.8.8,8.8.4.4"),
    # --- Optional custom script ---
    ("POST_SCRIPT_URL", "URL of post-install shell script (optional)", False, ""),
    # --- LLM Agent (optional) ---
    ("LITELLM_MODEL",   "LLM model for agent (e.g. gpt-4o)", False, ""),
    ("LITELLM_API_KEY", "LLM API key (optional)",           True,  ""),
]


def _read_existing() -> dict[str, str]:
    """Load existing config.env values."""
    if not CONFIG_PATH.exists():
        return {}
    values: dict[str, str] = {}
    for line in CONFIG_PATH.read_text().splitlines():
        line = line.strip()
        if line.startswith("#") or "=" not in line:
            continue
        key, _, val = line.partition("=")
        values[key.strip()] = val.strip().strip('"')
    return values


def _write_config(values: dict[str, str]) -> None:
    ensure_meshpi_dir()
    lines = [
        "# meshpi host configuration",
        "# Generated by: meshpi config",
        "# ⚠️  Keep this file private – it contains credentials",
        "",
    ]
    for key, val in values.items():
        lines.append(f'{key}="{val}"')
    CONFIG_PATH.write_text("\n".join(lines) + "\n")
    CONFIG_PATH.chmod(0o600)


def run_config_wizard(skip_existing: bool = False) -> None:
    """Interactive wizard to build config.env."""
    console.print(Panel.fit(
        "[bold cyan]meshpi config wizard[/bold cyan]\n"
        "Configure this machine as a MeshPi HOST.\n"
        "Values will be encrypted before sending to clients.",
        border_style="cyan",
    ))

    existing = _read_existing()
    new_values: dict[str, str] = dict(existing)

    # Try to auto-detect SSH public key
    default_ssh_key_path = Path.home() / ".ssh" / "id_rsa.pub"
    if default_ssh_key_path.exists() and not existing.get("SSH_PUBLIC_KEY"):
        existing["SSH_PUBLIC_KEY"] = default_ssh_key_path.read_text().strip()

    for key, label, sensitive, default in CONFIG_FIELDS:
        current = existing.get(key, default)

        if skip_existing and current:
            new_values[key] = current
            continue

        if current:
            display_current = "****" if sensitive else current
            prompt_label = f"[cyan]{label}[/cyan] (current: [dim]{display_current}[/dim])"
        else:
            prompt_label = f"[cyan]{label}[/cyan]"

        if sensitive:
            val = getpass.getpass(f"  {label}: ") or current
        else:
            val = Prompt.ask(f"  {prompt_label}", default=current or default)

        new_values[key] = val

    # Summary
    console.print("\n[bold]Configuration summary:[/bold]")
    for key, val in new_values.items():
        is_sensitive = any(f[0] == key and f[2] for f in CONFIG_FIELDS)
        display = "****" if is_sensitive and val else val
        console.print(f"  [dim]{key}[/dim] = {display}")

    if Confirm.ask("\n[green]Save configuration?[/green]", default=True):
        _write_config(new_values)
        console.print(f"\n[green]✓[/green] Saved to [bold]{CONFIG_PATH}[/bold]")
    else:
        console.print("[yellow]Aborted. No changes saved.[/yellow]")


def load_config() -> dict[str, str]:
    """Load config.env from host machine. Raises if not found."""
    if not CONFIG_PATH.exists():
        raise FileNotFoundError(
            f"Config not found at {CONFIG_PATH}. Run [bold]meshpi config[/bold] first."
        )
    return _read_existing()
