"""``ilum logs`` command."""

from __future__ import annotations

import time

import typer

import ilum.cli.output as output_mod
from ilum.cli.defaults import resolve_profile_defaults
from ilum.core.kubernetes import KubeClient, PodStatus
from ilum.core.modules import ModuleResolver
from ilum.errors import IlumError, ModuleError


def _pod_health_key(pod: PodStatus) -> tuple[int, str]:
    """Return a sort key that ranks healthier pods first.

    Priority: Running+Ready (0), Running (1), everything else (2).
    Ties broken alphabetically by name for determinism.
    """
    if pod.phase == "Running" and pod.ready:
        return (0, pod.name)
    if pod.phase == "Running":
        return (1, pod.name)
    return (2, pod.name)


def _select_best_pod(pods: list[PodStatus]) -> PodStatus:
    """Pick the healthiest pod from the list."""
    return min(pods, key=_pod_health_key)


def logs(
    module: str = typer.Argument(..., help="Module name (e.g. core, jupyter, sql)."),
    release: str | None = typer.Option(
        None, "--release", "-r", show_default="from profile", help="Helm release name."
    ),
    namespace: str | None = typer.Option(
        None, "--namespace", "-n", show_default="from profile", help="Kubernetes namespace."
    ),
    context: str | None = typer.Option(
        None, "--context", show_default="from profile", help="Kubernetes context."
    ),
    follow: bool = typer.Option(False, "--follow", "-f", help="Stream logs in real time."),
    tail: int = typer.Option(100, "--tail", help="Number of lines to show (0 for all)."),
    container: str | None = typer.Option(
        None, "--container", "-c", help="Container name (auto-detected if omitted)."
    ),
    previous: bool = typer.Option(
        False, "--previous", "-p", help="Show logs from previously terminated container."
    ),
    max_duration: int = typer.Option(
        0, "--max-duration", help="Stop --follow after N seconds (0 = unlimited)."
    ),
) -> None:
    """Show logs for an Ilum module's pod."""
    release, namespace, context = resolve_profile_defaults(release, namespace, context)
    console = output_mod.console

    try:
        resolver = ModuleResolver()
        mod = resolver.get(module)

        if not mod.pod_label:
            raise ModuleError(
                f"Module '{module}' has no pod label configured.",
                suggestion="This module may not have a running pod to inspect.",
            )

        k8s = KubeClient(kubecontext=context)
        pods = k8s.list_pods_by_label(namespace, mod.pod_label)

        if not pods:
            console.error(f"No pods found for module '{module}' (label: {mod.pod_label}).")
            raise typer.Exit(code=1)

        pod = _select_best_pod(pods)
        if len(pods) > 1:
            console.info(f"Multiple pods found ({len(pods)}), showing logs for '{pod.name}'.")

        if not (pod.phase == "Running" and pod.ready):
            states = ", ".join(f"{p.name} ({p.phase}{'/Ready' if p.ready else ''})" for p in pods)
            console.warning(f"No healthy pod available for '{module}'. Pod states: {states}")

        # Validate container if specified
        if container and pod.containers and container not in pod.containers:
            valid = ", ".join(pod.containers)
            raise ModuleError(
                f"Container '{container}' not found in pod '{pod.name}'.",
                suggestion=f"Available containers: {valid}",
            )

        # Hint when multi-container pod and no -c given
        if not container and len(pod.containers) > 1:
            console.info(
                f"Pod has multiple containers: {', '.join(pod.containers)}. Use -c to select one."
            )

        tail_lines = tail if tail > 0 else None

        if follow:
            start = time.monotonic()
            try:
                for line in k8s.stream_pod_log(
                    namespace,
                    pod.name,
                    container=container,
                    tail_lines=tail_lines,
                    previous=previous,
                ):
                    typer.echo(line)
                    if max_duration > 0 and (time.monotonic() - start) >= max_duration:
                        console.info(f"Reached max duration ({max_duration}s), stopping.")
                        break
            except KeyboardInterrupt:
                pass  # Graceful exit on Ctrl+C
        else:
            output = k8s.read_pod_log(
                namespace,
                pod.name,
                container=container,
                tail_lines=tail_lines,
                previous=previous,
            )
            if output:
                typer.echo(output, nl=False)

    except IlumError as exc:
        console.handle_error(exc)
        raise typer.Exit(code=1) from exc
