"""Auth resource -- API key CRUD operations."""

from __future__ import annotations

from datetime import datetime
from typing import Any
from uuid import UUID

from mcpgateway_sdk._http import HTTPClient
from mcpgateway_sdk.models.api_key import ApiKey

_ENDPOINTS = {
    "create_api_key": ("POST", "/api/v1/users/me/api-keys"),
    "list_api_keys": ("GET", "/api/v1/users/me/api-keys"),
    "get_api_key": ("GET", "/api/v1/users/me/api-keys/{key_id}"),
    "rotate_api_key": ("POST", "/api/v1/users/me/api-keys/{key_id}/rotate"),
    "revoke_api_key": ("DELETE", "/api/v1/users/me/api-keys/{key_id}"),
}


class AuthResource:
    """Manage API keys for the authenticated user."""

    _endpoints = _ENDPOINTS

    def __init__(self, http: HTTPClient) -> None:
        self._http = http

    async def create_api_key(
        self,
        name: str,
        description: str | None = None,
        scopes: list[str] | None = None,
        expires_at: datetime | None = None,
        expires_in_days: int | None = None,
        environment: str = "live",
        rate_limit_rpm: int = 60,
    ) -> ApiKey:
        """Create a new API key.

        Args:
            name: Human-readable name for the key.
            description: Optional description.
            scopes: Permission scopes (e.g. ["tools:read", "tools:execute"]).
            expires_at: Absolute expiration datetime.
            expires_in_days: Relative expiration in days.
            environment: Target environment (default "live").
            rate_limit_rpm: Requests-per-minute limit (default 60).

        Returns:
            The created ApiKey, including the one-time ``key`` field.
        """
        body: dict[str, object] = {
            "name": name,
            "environment": environment,
            "rate_limit_rpm": rate_limit_rpm,
        }
        if description is not None:
            body["description"] = description
        if scopes is not None:
            body["scopes"] = scopes
        if expires_at is not None:
            body["expires_at"] = expires_at.isoformat()
        if expires_in_days is not None:
            body["expires_in_days"] = expires_in_days

        data = await self._http.request("POST", "/api/v1/users/me/api-keys", json=body)
        return ApiKey.model_validate(data)

    async def list_api_keys(self) -> list[ApiKey]:
        """List all API keys for the authenticated user.

        Returns:
            A list of ApiKey objects (extracted from the paginated response).
        """
        data: Any = await self._http.request("GET", "/api/v1/users/me/api-keys")
        items = data.get("items", []) if isinstance(data, dict) else data
        return [ApiKey.model_validate(item) for item in (items or [])]

    async def get_api_key(self, key_id: str | UUID) -> ApiKey:
        """Get a single API key by ID.

        Args:
            key_id: The UUID of the API key.

        Returns:
            The matching ApiKey.
        """
        data = await self._http.request("GET", f"/api/v1/users/me/api-keys/{key_id}")
        return ApiKey.model_validate(data)

    async def rotate_api_key(
        self, key_id: str | UUID, grace_period_hours: int = 24
    ) -> dict[str, Any]:
        """Rotate an API key. Returns the new key and rotation details.

        Args:
            key_id: The UUID of the API key to rotate.
            grace_period_hours: Hours before the old key is revoked (default 24).

        Returns:
            A dict with ``new_key`` (ApiKey-shaped), ``old_key_revoked`` (bool),
            and ``grace_period_ends_at`` (datetime string or null).
        """
        data: dict[str, Any] = await self._http.request(
            "POST",
            f"/api/v1/users/me/api-keys/{key_id}/rotate",
            json={"grace_period_hours": grace_period_hours},
        )
        return data

    async def revoke_api_key(self, key_id: str | UUID) -> None:
        """Revoke (delete) an API key.

        Args:
            key_id: The UUID of the API key to revoke.
        """
        await self._http.request("DELETE", f"/api/v1/users/me/api-keys/{key_id}")
