"""CLI commands for domains — add, remove, list, clear."""

from __future__ import annotations

import click

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


class _ColonGroup(click.Group):
    """Resolve colon-separated subcommands."""

    def resolve_command(
        self,
        ctx: click.Context,
        args: list[str],
    ) -> tuple[str | None, click.Command | None, list[str]]:
        cmd_name = args[0] if args else None
        if cmd_name and ":" in cmd_name:
            parts = cmd_name.split(":", 1)
            args = [parts[0], parts[1]] + args[1:]
        return super().resolve_command(ctx, args)


@click.group("domains", cls=_ColonGroup, invoke_without_command=True)
@click.option("--app", "-a", "app_flag", default=None, help="Target app.")
@click.pass_context
def domains(ctx: click.Context, app_flag: str | None) -> None:
    """Manage custom domains for an app."""
    ctx.ensure_object(dict)
    ctx.obj["_domains_app"] = app_flag

    if ctx.invoked_subcommand is not None:
        return

    # Default: list domains
    app_name = resolve_app(app_flag)
    factory = ctx.obj["factory"]
    domain_list = factory.domains.list(app_name)

    if not domain_list:
        info("No domains configured.")
        return

    rows = []
    for d in domain_list:
        rows.append(
            {
                "hostname": d.hostname,
                "type": d.process_type,
                "port": str(d.port),
                "tls": d.issuer or ("none" if not d.tls else "yes"),
                "source": "auto" if d.auto_generated else "custom",
            }
        )

    click.echo(f"=== {app_name} domains")
    render_table(
        rows,
        columns=["hostname", "type", "port", "tls", "source"],
    )


@domains.command("add")
@click.argument("hostname")
@click.option("--app", "-a", "app_flag", default=None, help="Target app.")
@click.option("--type", "process_type", default="web", help="Process type to route to.")
@click.option("--port", type=int, default=None, help="Target port.")
@click.option("--no-tls", is_flag=True, default=False, help="Skip TLS (HTTP only).")
@click.option("--issuer", default="letsencrypt-prod", help="cert-manager ClusterIssuer.")
@click.pass_context
def add(
    ctx: click.Context,
    hostname: str,
    app_flag: str | None,
    process_type: str,
    port: int | None,
    no_tls: bool,
    issuer: str,
) -> None:
    """Add a custom domain to an app."""
    parent_app = ctx.obj.get("_domains_app")
    app_name = resolve_app(app_flag or parent_app)
    factory = ctx.obj["factory"]

    domain = factory.domains.add(
        app_name,
        hostname,
        process_type=process_type,
        port=port,
        no_tls=no_tls,
        issuer=issuer,
        on_step=lambda msg: info(msg),
    )

    tls_info = domain.issuer if domain.tls else "none"
    success(f"Added domain {hostname} -> {domain.process_type}:{domain.port} (TLS: {tls_info})")


@domains.command("remove")
@click.argument("hostname")
@click.option("--app", "-a", "app_flag", default=None, help="Target app.")
@click.pass_context
def remove(
    ctx: click.Context,
    hostname: str,
    app_flag: str | None,
) -> None:
    """Remove a custom domain from an app."""
    parent_app = ctx.obj.get("_domains_app")
    app_name = resolve_app(app_flag or parent_app)
    factory = ctx.obj["factory"]

    factory.domains.remove(
        app_name,
        hostname,
        on_step=lambda msg: info(msg),
    )
    success(f"Removed domain '{hostname}'.")


@domains.command("clear")
@click.option("--app", "-a", "app_flag", default=None, help="Target app.")
@click.option("--confirm", is_flag=True, help="Skip confirmation prompt.")
@click.pass_context
def clear(
    ctx: click.Context,
    app_flag: str | None,
    confirm: bool,
) -> None:
    """Remove ALL domains (auto + custom)."""
    parent_app = ctx.obj.get("_domains_app")
    app_name = resolve_app(app_flag or parent_app)
    factory = ctx.obj["factory"]

    if not confirm:
        click.confirm(
            f"Remove all domains from app '{app_name}'?",
            abort=True,
        )

    factory.domains.clear(
        app_name,
        on_step=lambda msg: info(msg),
    )
    success("Cleared all domains.")
