"""CLI commands for releases — list, info, rollback, prune."""

from __future__ import annotations

import click

from kuberoku.cli.context import resolve_app
from kuberoku.cli.output import info, render_detail, render_table, success


@click.group("releases", invoke_without_command=True)
@click.option("--app", "-a", "app_flag", default=None, help="Target app.")
@click.option("--num", "-n", default=10, type=int, help="Number of releases to show.")
@click.pass_context
def releases(ctx: click.Context, app_flag: str | None, num: int) -> None:
    """List releases."""
    ctx.ensure_object(dict)
    ctx.obj["_releases_app"] = app_flag

    if ctx.invoked_subcommand is not None:
        return

    app_name = resolve_app(app_flag)
    factory = ctx.obj["factory"]
    release_list = factory.releases.list(app_name, num=num)

    if not release_list:
        info("No releases found.")
        return

    render_table(
        release_list,
        columns=["version", "description", "created_at", "created_by"],
    )


@releases.command("info")
@click.argument("version", type=int)
@click.option("--app", "-a", "app_flag", default=None, help="Target app.")
@click.pass_context
def info_cmd(ctx: click.Context, version: int, app_flag: str | None) -> None:
    """Show release details."""
    parent_app = ctx.obj.get("_releases_app")
    app_name = resolve_app(app_flag or parent_app)
    factory = ctx.obj["factory"]

    release = factory.releases.info(app_name, version)
    fields = {
        "Version": str(release.version),
        "Description": release.description,
        "Created at": str(release.created_at),
        "Created by": release.created_by,
    }
    if release.images:
        fields["Images"] = ", ".join(f"{k}={v}" for k, v in release.images.items())
    if release.commit:
        fields["Commit"] = release.commit
    if release.ref:
        fields["Ref"] = release.ref
    render_detail(f"Release v{release.version}", fields)


@releases.command("rollback")
@click.argument("version", type=int, required=False, default=None)
@click.option("--app", "-a", "app_flag", default=None, help="Target app.")
@click.pass_context
def rollback_cmd(ctx: click.Context, version: int | None, app_flag: str | None) -> None:
    """Roll back to a previous release."""
    parent_app = ctx.obj.get("_releases_app")
    app_name = resolve_app(app_flag or parent_app)
    factory = ctx.obj["factory"]

    release = factory.releases.rollback(app_name, version=version, on_step=lambda msg: info(msg))
    success(f"Rolled back to v{release.version}.")


@releases.command("prune")
@click.option("--keep", default=50, type=int, help="Number of releases to keep.")
@click.option("--app", "-a", "app_flag", default=None, help="Target app.")
@click.pass_context
def prune_cmd(ctx: click.Context, keep: int, app_flag: str | None) -> None:
    """Prune old releases."""
    parent_app = ctx.obj.get("_releases_app")
    app_name = resolve_app(app_flag or parent_app)
    factory = ctx.obj["factory"]

    deleted = factory.releases.prune(app_name, keep=keep, on_step=lambda msg: info(msg))
    if deleted > 0:
        success(f"Pruned {deleted} old releases.")
    else:
        info("Nothing to prune.")
