from __future__ import annotations

import os

import typer

from ksef_client.exceptions import KsefApiError, KsefHttpError, KsefRateLimitError

from ..auth.keyring_store import get_token_store_mode
from ..auth.manager import resolve_base_url
from ..context import profile_label, require_context, require_profile
from ..errors import CliError
from ..exit_codes import ExitCode
from ..output import get_renderer
from ..sdk.adapters import run_health_check

app = typer.Typer(help="Run connectivity and diagnostics checks.")


def _append_token_store_check(result: dict[str, object]) -> None:
    checks_obj = result.get("checks")
    if not isinstance(checks_obj, list):
        checks_obj = []
        result["checks"] = checks_obj

    checks = checks_obj
    for item in checks:
        if isinstance(item, dict) and item.get("name") == "token_store":
            return

    mode = get_token_store_mode()
    checks.append(
        {
            "name": "token_store",
            "status": "WARN" if mode in {"plaintext-fallback", "unavailable"} else "PASS",
            "message": mode,
        }
    )


def _render_error(ctx: typer.Context, command: str, exc: Exception) -> None:
    cli_ctx = require_context(ctx)
    renderer = get_renderer(cli_ctx)

    if isinstance(exc, CliError):
        renderer.error(
            command=command,
            profile=profile_label(cli_ctx),
            code=exc.code.name,
            message=exc.message,
            hint=exc.hint,
        )
        raise typer.Exit(int(exc.code))

    if isinstance(exc, KsefRateLimitError):
        hint = f"Retry-After: {exc.retry_after}" if exc.retry_after else "Wait and retry."
        renderer.error(
            command=command,
            profile=profile_label(cli_ctx),
            code="RATE_LIMIT",
            message=str(exc),
            hint=hint,
        )
        raise typer.Exit(int(ExitCode.RETRY_EXHAUSTED))

    if isinstance(exc, (KsefApiError, KsefHttpError)):
        renderer.error(
            command=command,
            profile=profile_label(cli_ctx),
            code="API_ERROR",
            message=str(exc),
            hint="Check KSeF response and request parameters.",
        )
        raise typer.Exit(int(ExitCode.API_ERROR))

    renderer.error(
        command=command,
        profile=profile_label(cli_ctx),
        code="UNEXPECTED",
        message=str(exc),
        hint="Run with -v and inspect logs.",
    )
    raise typer.Exit(int(ExitCode.CONFIG_ERROR))


@app.command("check")
def health_check(
    ctx: typer.Context,
    dry_run: bool = typer.Option(
        False, "--dry-run", help="Run checks without business operations."
    ),
    check_auth: bool = typer.Option(
        False, "--check-auth", help="Fail if no stored authentication token is found."
    ),
    check_certs: bool = typer.Option(
        False, "--check-certs", help="Validate required KSeF public certificate usages."
    ),
    base_url: str | None = typer.Option(
        None, "--base-url", help="Override KSeF base URL for this command."
    ),
) -> None:
    cli_ctx = require_context(ctx)
    renderer = get_renderer(cli_ctx)
    profile = profile_label(cli_ctx)
    try:
        profile = require_profile(cli_ctx)
        result = run_health_check(
            profile=profile,
            base_url=resolve_base_url(base_url or os.getenv("KSEF_BASE_URL"), profile=profile),
            dry_run=dry_run,
            check_auth=check_auth,
            check_certs=check_certs,
        )
        _append_token_store_check(result)
    except Exception as exc:
        _render_error(ctx, "health.check", exc)
    renderer.success(command="health.check", profile=profile, data=result)
