"""CLI commands for managing existing Kubernetes clusters (status, delete, kubeconfig)."""
from pathlib import Path

import click

from k4s.cli.state import CliState
from k4s.cli.verbosity import apply_command_ui_overrides
from k4s.core.cluster import ClusterError, build_nodes_from_contexts
from k4s.core.executor import Executor


@click.group()
@click.pass_context
def cluster(ctx):
    """Manage existing Kubernetes clusters (status, delete, kubeconfig)."""
    pass


@cluster.command("kubeconfig")
@click.option("--control-plane", "control_plane_context", required=True, help="Context name of the control-plane node.")
@click.option("--output", "output_name", default="default", show_default=True, help="Output filename (written to ~/.kube/k4s/<name>.yaml).")
@click.pass_context
def kubeconfig(ctx, control_plane_context, output_name):
    state: CliState = ctx.obj["state"]
    ui = state.ui
    try:
        c = state.contexts.resolve(control_plane_context)
    except KeyError as e:
        ui.error(str(e))
        ctx.exit(2)
    if not c.host:
        ui.error(f"Context '{c.name}' has no host.")
        ctx.exit(2)

    sudo = (c.username or "").lower() not in {"root"}
    kube_dir = Path.home() / ".kube" / "k4s"
    kube_dir.mkdir(parents=True, exist_ok=True)
    local_kubeconfig = kube_dir / f"{output_name}.yaml"

    with ui.step("Fetching kubeconfig"):
        with Executor(c.to_server_config()) as ex:
            content = ex.read_remote_file_content("/etc/rancher/rke2/rke2.yaml", use_sudo=sudo)
        content = content.replace("127.0.0.1", c.host)
        local_kubeconfig.write_text(content, encoding="utf-8")

    ui.success(f"Kubeconfig written: {str(local_kubeconfig)}")


@cluster.command("status")
@click.option("--control-plane", "control_plane_context", required=True, help="Context name of the control-plane node.")
@click.option("-q", "--quiet", is_flag=True, help="Only print final results and errors.")
@click.option("-v", "--verbose", count=True, help="Increase verbosity (-v logs, -vv debug).")
@click.pass_context
def status(ctx, control_plane_context, quiet, verbose):
    state: CliState = ctx.obj["state"]
    apply_command_ui_overrides(ctx, state, quiet=quiet, verbose=verbose)
    ui = state.ui

    try:
        c = state.contexts.resolve(control_plane_context)
    except KeyError as e:
        ui.error(str(e))
        ctx.exit(2)
    if not c.host:
        ui.error(f"Context '{c.name}' has no host.")
        ctx.exit(2)

    sudo = (c.username or "").lower() not in {"root"}
    with ui.step("Checking rke2-server"):
        with Executor(c.to_server_config()) as ex:
            rc, out, err = ex.execute("systemctl is-active rke2-server", use_sudo=sudo)
            if rc != 0:
                raise click.ClickException(f"rke2-server is not active on {c.host}: {err or out}")
    ui.success(f"rke2-server active on {c.host}")

    with ui.step("Listing nodes"):
        with Executor(c.to_server_config()) as ex:
            cmd = "/var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get nodes -o wide"
            rc, out, err = ex.execute(cmd, use_sudo=sudo)
            if rc != 0:
                ui.warning(f"Failed to list nodes: {err or out}")
            else:
                ui.info(out)


@cluster.command("delete")
@click.option("--control-plane", "control_planes", multiple=True, required=True, help="Context name for a control-plane node.")
@click.option("--worker", "workers", multiple=True, help="Context name for a worker node.")
@click.option("--yes", is_flag=True, help="Skip confirmation prompt.")
@click.option("--dry-run", is_flag=True, help="Print the plan without applying changes.")
@click.option("-q", "--quiet", is_flag=True, help="Only print final results and errors.")
@click.option("-v", "--verbose", count=True, help="Increase verbosity (-v logs, -vv debug).")
@click.pass_context
def delete(ctx, control_planes, workers, yes, dry_run, quiet, verbose):
    """Uninstall RKE2 from the specified nodes."""
    state: CliState = ctx.obj["state"]
    apply_command_ui_overrides(ctx, state, quiet=quiet, verbose=verbose)
    ui = state.ui

    try:
        nodes = build_nodes_from_contexts(state.contexts, control_planes=list(control_planes), workers=list(workers))
    except (KeyError, ClusterError) as e:
        ui.error(str(e))
        ctx.exit(2)

    if dry_run:
        ui.info("Planned steps:")
        for n in nodes:
            script = "rke2-agent-uninstall.sh" if n.role == "worker" else "rke2-uninstall.sh"
            ui.info(f"  - Run {script} on {n.context.name} ({n.context.host})")
        return

    total = len(nodes)
    if not yes and not click.confirm(f"Uninstall RKE2 from {total} node(s)?", default=False):
        ui.info("Cancelled.")
        return

    failures = []

    for n in [x for x in nodes if x.role == "worker"]:
        with ui.step(f"Uninstalling rke2-agent on {n.context.name}"):
            sudo = (n.context.username or "").lower() not in {"root"}
            try:
                with Executor(n.context.to_server_config()) as ex:
                    rc, _, err = ex.execute("/usr/local/bin/rke2-agent-uninstall.sh", use_sudo=sudo)
                    if rc != 0:
                        failures.append(f"{n.context.name}: {err}")
            except Exception as e:
                failures.append(f"{n.context.name}: {e}")

    for n in [x for x in nodes if x.role == "control-plane"]:
        with ui.step(f"Uninstalling rke2-server on {n.context.name}"):
            sudo = (n.context.username or "").lower() not in {"root"}
            try:
                with Executor(n.context.to_server_config()) as ex:
                    rc, _, err = ex.execute("/usr/local/bin/rke2-uninstall.sh", use_sudo=sudo)
                    if rc != 0:
                        failures.append(f"{n.context.name}: {err}")
            except Exception as e:
                failures.append(f"{n.context.name}: {e}")

    if failures:
        ui.error("Some nodes failed to uninstall:")
        for f in failures:
            ui.error(f"  - {f}")
        ctx.exit(1)
    else:
        state.history.append(
            action="cluster-delete",
            product="cluster",
            params={
                "control_planes": list(control_planes),
                "workers": list(workers),
            },
        )
        ui.success("Cluster uninstalled successfully.")
