"""Credentials resource — reusable KYC credentials."""

from __future__ import annotations

from dataclasses import asdict
from typing import Any, Dict, Optional, TYPE_CHECKING

if TYPE_CHECKING:
    from ..http_client import AsyncHttpClient, HttpClient

__all__ = ["Credentials", "AsyncCredentials"]


class Credentials:
    """Reusable KYC credentials (synchronous).

    Example::

        cred = verilock.credentials.create(
            CreateCredentialParams(
                session_id="sess_123",
                shared_fields=["full_name", "date_of_birth", "nationality"],
                expires_in_days=90,
            )
        )
        # Share cred["token"] with the relying party
    """

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

    def create(
        self,
        params: Any,
        *,
        idempotency_key: Optional[str] = None,
    ) -> Dict[str, Any]:
        """Create a reusable KYC credential from an approved session.

        Args:
            params: A :class:`~verilock.types.credentials.CreateCredentialParams` or dict.

        Returns:
            Credential object with ``id``, ``token``, ``status``, and ``shared_fields``.
        """
        body = asdict(params) if hasattr(params, "__dataclass_fields__") else params
        body = {k: v for k, v in body.items() if v is not None}
        return self._http.post("/v1/credentials", body, idempotency_key=idempotency_key)

    def retrieve(
        self,
        credential_id: str,
        *,
        idempotency_key: Optional[str] = None,
    ) -> Dict[str, Any]:
        """Retrieve credential details by ID.

        Args:
            credential_id: The credential ID.

        Returns:
            Full credential object.
        """
        return self._http.get(
            f"/v1/credentials/{credential_id}", idempotency_key=idempotency_key
        )

    def verify(
        self,
        params: Any,
        *,
        idempotency_key: Optional[str] = None,
    ) -> Dict[str, Any]:
        """Verify a credential token and retrieve the shared identity data.

        Args:
            params: A :class:`~verilock.types.credentials.VerifyCredentialParams` or dict.

        Returns:
            Verification response with ``valid``, ``shared_data``, and ``verification_result``.
        """
        body = asdict(params) if hasattr(params, "__dataclass_fields__") else params
        body = {k: v for k, v in body.items() if v is not None}
        return self._http.post(
            "/v1/credentials/verify", body, idempotency_key=idempotency_key
        )

    def revoke(
        self,
        credential_id: str,
        *,
        idempotency_key: Optional[str] = None,
    ) -> Dict[str, Any]:
        """Revoke a credential so it can no longer be used for verification.

        Args:
            credential_id: The credential ID to revoke.

        Returns:
            Response with a ``message`` confirming revocation.
        """
        return self._http.delete(
            f"/v1/credentials/{credential_id}", idempotency_key=idempotency_key
        )


class AsyncCredentials:
    """Reusable KYC credentials (asynchronous)."""

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

    async def create(
        self,
        params: Any,
        *,
        idempotency_key: Optional[str] = None,
    ) -> Dict[str, Any]:
        """Create a reusable KYC credential from an approved session."""
        body = asdict(params) if hasattr(params, "__dataclass_fields__") else params
        body = {k: v for k, v in body.items() if v is not None}
        return await self._http.post(
            "/v1/credentials", body, idempotency_key=idempotency_key
        )

    async def retrieve(
        self,
        credential_id: str,
        *,
        idempotency_key: Optional[str] = None,
    ) -> Dict[str, Any]:
        """Retrieve credential details by ID."""
        return await self._http.get(
            f"/v1/credentials/{credential_id}", idempotency_key=idempotency_key
        )

    async def verify(
        self,
        params: Any,
        *,
        idempotency_key: Optional[str] = None,
    ) -> Dict[str, Any]:
        """Verify a credential token and retrieve the shared identity data."""
        body = asdict(params) if hasattr(params, "__dataclass_fields__") else params
        body = {k: v for k, v in body.items() if v is not None}
        return await self._http.post(
            "/v1/credentials/verify", body, idempotency_key=idempotency_key
        )

    async def revoke(
        self,
        credential_id: str,
        *,
        idempotency_key: Optional[str] = None,
    ) -> Dict[str, Any]:
        """Revoke a credential so it can no longer be used for verification."""
        return await self._http.delete(
            f"/v1/credentials/{credential_id}", idempotency_key=idempotency_key
        )
