"""MCP tools for managing BPA instance profiles.

Profiles are stored in ~/.config/mcp-eregistrations-bpa/profiles.json.
They allow a single MCP server process to target multiple BPA instances
by passing instance=<name> to any tool.

No authentication is required for these tools.
"""

from __future__ import annotations

from typing import Any

from fastmcp.exceptions import ToolError

from mcp_eregistrations_bpa.auth.credentials import (
    store_cas_secret,
)
from mcp_eregistrations_bpa.config import (
    Config,
    load_profiles,
    save_profiles,
)

__all__ = [
    "instance_list",
    "instance_add",
    "instance_remove",
    "register_instance_tools",
]


async def instance_list() -> dict[str, Any]:
    """List all configured BPA instance profiles. No authentication required.

    Returns:
        dict with profiles (name -> url, auto_login status) and total count.
    """
    from mcp_eregistrations_common.auth_store import get_credentials as auth_store_get

    profiles = load_profiles()

    return {
        "profiles": {
            name: {
                "bpa_instance_url": profile.get("bpa_instance_url"),
                "ds_url": profile.get("ds_url"),
                "gdb_url": profile.get("gdb_url"),
                "auto_login": auth_store_get(name) is not None,
            }
            for name, profile in profiles.items()
        },
        "total": len(profiles),
    }


async def instance_add(
    name: str,
    bpa_instance_url: str,
    ds_url: str | None = None,
    gdb_url: str | None = None,
    keycloak_url: str | None = None,
    keycloak_realm: str | None = None,
    keycloak_client_id: str = "mcp-eregistrations-bpa",
    cas_url: str | None = None,
    cas_client_id: str | None = None,
    cas_client_secret: str | None = None,
    username: str | None = None,
    password: str | None = None,
) -> dict[str, Any]:
    """Register a BPA instance profile with optional auto-login credentials.

    Validates the config before saving. When username and password are
    provided, stores them in the system keyring for transparent auto-login
    (no explicit auth_login needed).

    Args:
        name: Profile name (e.g. "jamaica", "nigeria").
        bpa_instance_url: BPA instance URL (must use HTTPS).
        ds_url: Display System URL for the applicant portal (optional).
        gdb_url: GDB (Generic Database Builder) URL (optional).
        keycloak_url: Keycloak server URL (optional).
        keycloak_realm: Keycloak realm name (optional).
        keycloak_client_id: Keycloak client ID (default: mcp-eregistrations-bpa).
        cas_url: CAS server URL for legacy auth (optional).
        cas_client_id: CAS client ID (required if cas_url set).
        cas_client_secret: CAS client secret (required if cas_url set).
        username: BPA username for auto-login (optional).
        password: BPA password for auto-login (required if username set).

    Returns:
        dict with name, bpa_instance_url, instance_id, auto_login status.
    """
    if not name or not name.strip():
        raise ToolError("Profile name is required.")
    if username and not password:
        raise ToolError("Password is required when username is provided.")
    if password and not username:
        raise ToolError("Username is required when password is provided.")
    name = name.strip().lower()

    # Validate config by constructing a Config object
    profile: dict[str, Any] = {"bpa_instance_url": bpa_instance_url}
    if ds_url:
        profile["ds_url"] = ds_url
    if gdb_url:
        profile["gdb_url"] = gdb_url
    if keycloak_url:
        profile["keycloak_url"] = keycloak_url
    if keycloak_realm:
        profile["keycloak_realm"] = keycloak_realm
    if keycloak_client_id != "mcp-eregistrations-bpa":
        profile["keycloak_client_id"] = keycloak_client_id
    if cas_url:
        profile["cas_url"] = cas_url
    if cas_client_id:
        profile["cas_client_id"] = cas_client_id
    if cas_client_secret:
        profile["cas_client_secret"] = cas_client_secret

    try:
        config = Config(**profile)
    except Exception as e:
        raise ToolError(f"Invalid instance configuration: {e}")

    # Store CAS secret in keyring to avoid plaintext in profiles.json
    secret_warning: str | None = None
    if cas_client_secret:
        stored = store_cas_secret(config.instance_id, cas_client_secret)
        if stored:
            profile["cas_client_secret"] = "__keyring__"
        else:
            secret_warning = (
                "Keyring unavailable: CAS client secret stored in plaintext. "
                "Install a keyring backend for secure secret storage."
            )

    # Store user credentials in AuthStore for auto-login
    auto_login_status: str | None = None
    if username and password:
        try:
            from mcp_eregistrations_common.auth_store import (
                store_credentials as auth_store_creds,
            )

            auth_store_creds(
                name,
                username,
                password,
                keycloak_url=keycloak_url,
                keycloak_realm=keycloak_realm,
            )
            auto_login_status = "enabled"
            # Best-effort login validation
            try:
                from mcp_eregistrations_bpa.auth.permissions import password_login

                login_result = await password_login(username, password, config=config)
                if login_result.get("success"):
                    auto_login_status = "enabled_and_verified"
                else:
                    auto_login_status = "enabled_not_verified"
            except Exception:
                auto_login_status = "enabled_not_verified"
        except Exception:
            auto_login_status = "store_failed"

    profiles = load_profiles()
    replaced = name in profiles
    profiles[name] = profile
    save_profiles(profiles)

    result: dict[str, Any] = {
        "name": name,
        "bpa_instance_url": config.bpa_instance_url,
        "instance_id": config.instance_id,
        "created": not replaced,
        "replaced": replaced,
    }
    if secret_warning:
        result["cas_secret_warning"] = secret_warning
    if auto_login_status:
        result["auto_login"] = auto_login_status
    return result


async def instance_remove(name: str) -> dict[str, Any]:
    """Remove a BPA instance profile by name. No authentication required.

    Args:
        name: Profile name to remove.

    Returns:
        dict with removed (bool), name.
    """
    if not name or not name.strip():
        raise ToolError("Profile name is required.")
    name = name.strip().lower()

    profiles = load_profiles()
    if name not in profiles:
        available = ", ".join(sorted(profiles.keys())) or "none"
        raise ToolError(f"Profile '{name}' not found. Available profiles: {available}.")

    # Clean up auth data from AuthStore before removing profile
    try:
        from mcp_eregistrations_common.auth_store import delete_instance

        delete_instance(name)
    except Exception:
        pass

    del profiles[name]
    save_profiles(profiles)

    return {"removed": True, "name": name}


def register_instance_tools(mcp: Any) -> None:
    """Register instance management tools with the MCP server.

    Args:
        mcp: The FastMCP server instance.
    """
    from mcp_eregistrations_bpa.tools.annotations import DESTRUCTIVE, READ, WRITE

    mcp.tool(annotations=READ)(instance_list)
    mcp.tool(annotations=WRITE)(instance_add)
    mcp.tool(annotations=DESTRUCTIVE)(instance_remove)
