"""appxen update — self-update the CLI."""

from __future__ import annotations

import shutil
import subprocess
import sys
import sysconfig
import tempfile

import typer

from appxen_cli import __version__
from appxen_cli.display import console, error, success
from appxen_cli.version_check import get_latest_version, _parse_version

WHEEL_URL = "https://appxen.ai/releases/appxen-{version}-py3-none-any.whl"


def _is_pipx_install() -> bool:
    """Detect if the CLI was installed via pipx."""
    if not shutil.which("pipx"):
        return False
    paths = sysconfig.get_path("purelib", vars={"base": sys.prefix}) or ""
    return "pipx" in paths


def _try_run(cmd: list[str]) -> bool:
    """Run a command, return True on success."""
    try:
        result = subprocess.run(cmd, capture_output=True, text=True)
        return result.returncode == 0
    except FileNotFoundError:
        return False


def _install_from_wheel(version: str, use_pipx: bool) -> bool:
    """Download wheel from S3 and install it."""
    import httpx

    url = WHEEL_URL.format(version=version)
    wheel_name = f"appxen-{version}-py3-none-any.whl"

    try:
        console.print(f"[dim]Downloading {wheel_name}...[/dim]")
        resp = httpx.get(url, timeout=30.0, follow_redirects=True)
        resp.raise_for_status()
    except Exception:
        return False

    with tempfile.TemporaryDirectory() as tmpdir:
        wheel_path = f"{tmpdir}/{wheel_name}"
        with open(wheel_path, "wb") as f:
            f.write(resp.content)

        if use_pipx:
            return _try_run(["pipx", "install", wheel_path, "--force"])
        else:
            return _try_run([sys.executable, "-m", "pip", "install", wheel_path])


def update(
    check: bool = typer.Option(False, "--check", help="Only show version info, don't install"),
) -> None:
    """Update the AppXen CLI to the latest version."""
    console.print(f"[bold]Current version:[/bold] {__version__}")

    latest = get_latest_version(use_cache=False)
    if latest is None:
        error("Could not check for updates. Try again later.")
        raise typer.Exit(1)

    console.print(f"[bold]Latest version:[/bold]  {latest}")

    if _parse_version(latest) <= _parse_version(__version__):
        success(f"Already up to date (v{__version__})")
        return

    if check:
        console.print(
            f"\n[yellow]Update available:[/yellow] {__version__} → {latest}"
        )
        console.print("Run [bold]appxen update[/bold] to upgrade.")
        return

    console.print(f"\nUpdating appxen {__version__} → {latest}...")

    use_pipx = _is_pipx_install()
    installed = False

    # Try PyPI first
    if use_pipx:
        installed = _try_run(["pipx", "upgrade", "appxen"])
    else:
        installed = _try_run([sys.executable, "-m", "pip", "install", "--upgrade", "appxen"])

    # Fall back to S3 wheel
    if not installed:
        console.print("[dim]PyPI upgrade failed, trying appxen.ai...[/dim]")
        installed = _install_from_wheel(latest, use_pipx)

    if installed:
        success(f"Updated to appxen v{latest}")
        console.print("Run [bold]appxen --version[/bold] to verify.")
    else:
        error("Update failed.")
        console.print(
            f"Try manually: [bold]pip install https://appxen.ai/releases/"
            f"appxen-{latest}-py3-none-any.whl[/bold]"
        )
        raise typer.Exit(1)
