from __future__ import annotations

from typing import Any

from mcp.types import ToolAnnotations

from mcp_eregistrations_keycloak.keycloak_client import (
    KeycloakAdminClient,
    KeycloakClientError,
    translate_error,
)
from mcp_eregistrations_keycloak.server import mcp
from mcp_eregistrations_keycloak.tools.validation import (
    _extract_items,
    _resolve_realm,
)


@mcp.tool(annotations=ToolAnnotations(readOnlyHint=True))
async def kc_debug_scan_realm(
    realm: str | None = None,
    instance: str | None = None,
) -> dict[str, Any]:
    """Scan a realm for common configuration issues.

    Checks: empty composites, roles without descriptions, users without
    custom roles, theme status, brute force protection.

    Args:
        realm: Realm name, or None for instance default.
        instance: Instance name, or None for auto-select.

    Returns:
        dict with findings, warnings, realm_status.
    """
    try:
        async with KeycloakAdminClient.for_instance(instance) as client:
            r = _resolve_realm(realm, instance, client)
            realm_config = await client.get(f"/realms/{r}")
            roles = await client.get(f"/realms/{r}/roles")
            items = _extract_items(roles)
            users = await client.get(f"/realms/{r}/users", first=0, max=20)
            user_items = _extract_items(users)

            warnings: list[str] = []

            # Check roles without descriptions
            no_desc = [role["name"] for role in items if not role.get("description")]
            if no_desc:
                warnings.append(
                    f"{len(no_desc)} role(s) without description:"
                    f" {', '.join(no_desc[:10])}"
                )

            # Check empty composite roles
            empty_composites = [role["name"] for role in items if role.get("composite")]

            # Check brute force protection
            if not realm_config.get("bruteForceProtected"):
                warnings.append("Brute force protection is DISABLED")

            # Check realm enabled state
            if not realm_config.get("enabled"):
                warnings.append("Realm is DISABLED")

            # Check themes
            theme_status = {
                field: realm_config.get(field, "default")
                for field in ("loginTheme", "accountTheme", "adminTheme", "emailTheme")
            }

            return {
                "realm": r,
                "enabled": realm_config.get("enabled"),
                "role_count": len(items),
                "composite_roles": empty_composites,
                "user_sample_count": len(user_items),
                "brute_force_protected": realm_config.get("bruteForceProtected", False),
                "themes": theme_status,
                "warnings": warnings,
                "warning_count": len(warnings),
            }
    except KeycloakClientError as e:
        raise translate_error(e, resource_type="realm scan", resource_id=realm) from e


@mcp.tool(annotations=ToolAnnotations(readOnlyHint=True))
async def kc_connection_status(
    instance: str | None = None,
) -> dict[str, Any]:
    """Check Keycloak connectivity, version, and token status.

    Args:
        instance: Instance name, or None for auto-select.

    Returns:
        dict with connected, version, realm_count, token_status.
    """
    try:
        async with KeycloakAdminClient.for_instance(instance) as client:
            # Try serverinfo for version
            version = None
            try:
                info = await client.get("/serverinfo")
                system_info = info.get("systemInfo", {})
                version = system_info.get("version")
            except Exception:
                pass  # serverinfo may not be accessible with limited permissions

            # Count realms
            realms = await client.get("/realms")
            items = _extract_items(realms)

            return {
                "connected": True,
                "instance": instance,
                "keycloak_url": client.base_url,
                "version": version,
                "realm_count": len(items),
                "realms": [r["realm"] for r in items],
                "default_realm": client.default_realm,
            }
    except KeycloakClientError as e:
        raise translate_error(e, resource_type="connection status") from e
