import argparse
import sys
from dataclasses import dataclass
from datetime import datetime
from pathlib import Path

from nebula_cert_manager.exceptions import CertManagerError, RegistryNotFoundError
from nebula_cert_manager.lighthouses import extract_lighthouses
from nebula_cert_manager.models import LighthouseConfig
from nebula_cert_manager.nebula_config import load_nebula_config
from nebula_cert_manager.registry import RegistryManager


@dataclass
class RegistryInfo:
    registry_dir: Path
    ca_name: str
    ca_fingerprint: str
    ca_created_at: datetime
    network_cidr: str | None
    lighthouses: dict[str, LighthouseConfig]
    active_certs: int
    revoked_certs: int


def add_parser(subparsers: argparse._SubParsersAction) -> None:
    parser = subparsers.add_parser("info", help="Show registry and CA information")
    parser.set_defaults(func=run)


def get_registry_info(
    registry_mgr: RegistryManager,
) -> RegistryInfo:
    """Collect registry information.

    Raises RegistryNotFoundError.
    """
    if not registry_mgr.exists():
        raise RegistryNotFoundError()

    registry = registry_mgr.load()

    all_certs = [c for certs in registry.clients.values() for c in certs]
    active = sum(1 for c in all_certs if not c.revoked)
    revoked = sum(1 for c in all_certs if c.revoked)

    nebula_cfg = load_nebula_config(registry_mgr.registry_dir)

    network_cidr: str | None = None
    if nebula_cfg is not None and nebula_cfg.network is not None:
        network_cidr = nebula_cfg.network.cidr

    lighthouses: dict[str, LighthouseConfig] = {}
    if nebula_cfg is not None and nebula_cfg.hosts is not None:
        lighthouses = extract_lighthouses(nebula_cfg.hosts)

    return RegistryInfo(
        registry_dir=registry_mgr.registry_dir,
        ca_name=registry.ca.name,
        ca_fingerprint=registry.ca.fingerprint,
        ca_created_at=registry.ca.created_at,
        network_cidr=network_cidr,
        lighthouses=lighthouses,
        active_certs=active,
        revoked_certs=revoked,
    )


def run(args: argparse.Namespace) -> None:
    try:
        info = get_registry_info(args.registry_mgr)
    except CertManagerError as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)

    print("Registry Information")
    print("=" * 40)
    print(f"Registry dir:    {info.registry_dir}")
    print()
    print("CA:")
    print(f"  Name:          {info.ca_name}")
    print(f"  Fingerprint:   {info.ca_fingerprint}")
    print(f"  Created:       {info.ca_created_at.strftime('%Y-%m-%d %H:%M:%S UTC')}")
    print()

    print("Network:")
    if info.network_cidr is not None:
        print(f"  CIDR:          {info.network_cidr}")
    else:
        print("  (not configured in nebula.config.yml)")
    print()

    print("Lighthouses:")
    if info.lighthouses:
        for name, lh in info.lighthouses.items():
            endpoints = [f"{ep}:{lh.listen_port}" for ep in lh.public_endpoints]
            print(f"  {name}: {lh.nebula_ip} -> {', '.join(endpoints)}")
    else:
        print("  (none configured)")
    print()
    print("Certificates:")
    print(f"  Active:        {info.active_certs}")
    print(f"  Revoked:       {info.revoked_certs}")
    print(f"  Total:         {info.active_certs + info.revoked_certs}")
