"""API key resource client."""

from __future__ import annotations

from collections.abc import Mapping
import datetime

from convexity_api_client import AuthenticatedClient, Client
from convexity_api_client.api.v1 import (
    create_api_key_v1_api_keys_post as _create_api_key,
)
from convexity_api_client.api.v1 import (
    get_api_key_usage_v1_api_keys_key_id_usage_get as _get_api_key_usage,
)
from convexity_api_client.api.v1 import (
    get_api_key_v1_api_keys_key_id_get as _get_api_key,
)
from convexity_api_client.api.v1 import (
    list_api_keys_v1_api_keys_get as _list_api_keys,
)
from convexity_api_client.api.v1 import (
    revoke_api_key_v1_api_keys_key_id_delete as _revoke_api_key,
)
from convexity_api_client.api.v1 import (
    rotate_api_key_v1_api_keys_key_id_rotate_post as _rotate_api_key,
)
from convexity_api_client.api.v1 import (
    update_api_key_v1_api_keys_key_id_patch as _update_api_key,
)
from convexity_api_client.models.api_key_list_response import ApiKeyListResponse
from convexity_api_client.models.api_key_permission import ApiKeyPermission
from convexity_api_client.models.api_key_response import ApiKeyResponse
from convexity_api_client.models.api_key_scope_roles import ApiKeyScopeRoles
from convexity_api_client.models.api_key_usage_stats import ApiKeyUsageStats
from convexity_api_client.models.create_api_key_request import CreateApiKeyRequest
from convexity_api_client.models.create_api_key_response import CreateApiKeyResponse
from convexity_api_client.models.update_api_key_request import UpdateApiKeyRequest
from convexity_api_client.types import UNSET, Unset


def _normalize_scope_permission(value: str | ApiKeyPermission) -> ApiKeyPermission:
    if isinstance(value, ApiKeyPermission):
        return value
    return ApiKeyPermission(value.upper())


def _build_scope_roles(
    scopes: Mapping[str, str | ApiKeyPermission] | ApiKeyScopeRoles | None | Unset,
) -> ApiKeyScopeRoles | None | Unset:
    if isinstance(scopes, Unset) or scopes is None:
        return scopes
    if isinstance(scopes, ApiKeyScopeRoles):
        return scopes
    org_role: ApiKeyPermission | Unset = UNSET
    project_role: ApiKeyPermission | Unset = UNSET
    if "org" in scopes:
        org_role = _normalize_scope_permission(scopes["org"])
    if "project" in scopes:
        project_role = _normalize_scope_permission(scopes["project"])
    return ApiKeyScopeRoles(org=org_role, project=project_role)


class ApiKeys:
    """Synchronous sub-client for user-scoped API key operations."""

    def __init__(self, api_client: AuthenticatedClient | Client) -> None:
        self._client = api_client

    def list(self, *, include_revoked: bool = False) -> ApiKeyListResponse:
        """List API keys for the authenticated user."""
        result = _list_api_keys.sync(client=self._client, include_revoked=include_revoked)
        if not isinstance(result, ApiKeyListResponse):
            return ApiKeyListResponse(items=[], total=0)
        return result

    def get(self, key_id: str) -> ApiKeyResponse | None:
        """Get a specific API key by ID."""
        result = _get_api_key.sync(key_id, client=self._client)
        if isinstance(result, ApiKeyResponse):
            return result
        return None

    def create(
        self,
        *,
        name: str,
        description: str | None | Unset = UNSET,
        expires_at: datetime.datetime | None | Unset = UNSET,
        rate_limit: int | None | Unset = UNSET,
        allowed_ips: list[str] | None | Unset = UNSET,
        scopes: Mapping[str, str | ApiKeyPermission] | ApiKeyScopeRoles | None | Unset = UNSET,
    ) -> CreateApiKeyResponse:
        """Create a new API key and return the one-time secret response."""
        body = CreateApiKeyRequest(
            name=name,
            description=description,
            expires_at=expires_at,
            rate_limit=rate_limit,
            allowed_ips=allowed_ips,
            scopes=_build_scope_roles(scopes),
        )
        result = _create_api_key.sync(client=self._client, body=body)
        if not isinstance(result, CreateApiKeyResponse):
            raise ValueError(f"Unexpected response when creating API key: {result}")
        return result

    def update(
        self,
        key_id: str,
        *,
        name: str | None | Unset = UNSET,
        description: str | None | Unset = UNSET,
        rate_limit: int | None | Unset = UNSET,
        allowed_ips: list[str] | None | Unset = UNSET,
        scopes: Mapping[str, str | ApiKeyPermission] | ApiKeyScopeRoles | None | Unset = UNSET,
    ) -> ApiKeyResponse:
        """Update an existing API key's metadata and/or scopes."""
        body = UpdateApiKeyRequest(
            name=name,
            description=description,
            rate_limit=rate_limit,
            allowed_ips=allowed_ips,
            scopes=_build_scope_roles(scopes),
        )
        result = _update_api_key.sync(key_id, client=self._client, body=body)
        if not isinstance(result, ApiKeyResponse):
            raise ValueError(f"Unexpected response when updating API key: {result}")
        return result

    def revoke(self, key_id: str) -> None:
        """Revoke an API key by ID."""
        _revoke_api_key.sync_detailed(key_id, client=self._client)

    def rotate(self, key_id: str) -> CreateApiKeyResponse:
        """Rotate an API key and return the new one-time secret response."""
        result = _rotate_api_key.sync(key_id, client=self._client)
        if not isinstance(result, CreateApiKeyResponse):
            raise ValueError(f"Unexpected response when rotating API key: {result}")
        return result

    def usage(self, key_id: str) -> ApiKeyUsageStats | None:
        """Get usage statistics for an API key."""
        result = _get_api_key_usage.sync(key_id, client=self._client)
        if isinstance(result, ApiKeyUsageStats):
            return result
        return None
