"""ievo update — self-update CLI to latest version from PyPI."""

from __future__ import annotations

import asyncio
import subprocess

import typer

from ievo.core.updater import (
    Installer,
    detect_installer,
    fetch_latest_version,
    get_current_version,
    run_upgrade,
)
from ievo.utils.console import error, info, step, success


def update() -> None:
    """Update ievo to the latest version from PyPI.

    Flow:
    1. Detect installer (uvx / uv tool / pip).
    2. UVX → informational message (auto-fetches latest), exit 0.
    3. Fetch latest version from PyPI.
    4. If current == latest → "up to date", exit 0.
    5. Run upgrade subprocess, report result.

    Exits with code 1 on network error, missing binary, or subprocess failure.
    """
    step("Checking for updates...")

    current = get_current_version()
    installer = detect_installer()

    if installer == Installer.UVX:
        info(
            f"ievo {current} — installed via [bold]uvx[/bold] (ephemeral)."
            "\nuvx always fetches the latest version on next run."
            "\nTo clear the cache: [bold]uv cache clean ievo[/bold]"
        )
        raise typer.Exit(0)

    try:
        latest = asyncio.run(fetch_latest_version())
    except Exception:
        error("Could not check for updates — version check failed.")
        raise typer.Exit(1) from None

    if current == latest:
        success(f"ievo {current} is already up to date.")
        raise typer.Exit(0)

    info(f"Current version: {current}")
    info(f"Latest version:  {latest}")
    step(f"Detected installer: {installer.value}")

    try:
        run_upgrade(installer)
        success(f"ievo updated to {latest}.")
    except FileNotFoundError:
        error(f"Could not find {installer.value} — is it installed?")
        raise typer.Exit(1) from None
    except subprocess.CalledProcessError as exc:
        error("Upgrade command failed.")
        if exc.stderr:
            info(exc.stderr.strip())
        raise typer.Exit(1) from None
