"""Main Verilock client classes for sync and async usage."""

from __future__ import annotations

import os
from typing import Optional

from .http_client import AsyncHttpClient, HttpClient
from .resources.sessions import AsyncSessions, Sessions
from .resources.aml import AsyncAml, Aml
from .resources.transactions import AsyncTransactions, Transactions
from .resources.biometric import AsyncBiometric, Biometric
from .resources.database import AsyncDatabase, Database
from .resources.face_search import AsyncFaceSearch, FaceSearch
from .resources.wallet import AsyncWallet, Wallet
from .resources.credentials import AsyncCredentials, Credentials
from .resources.age_verify import AsyncAgeVerify, AgeVerify

__all__ = ["Verilock", "AsyncVerilock"]


class Verilock:
    """Official Python client for the Verilock Identity Verification API.

    Example::

        from verilock import Verilock
        from verilock.types import CreateSessionParams, ScreenPersonParams

        client = Verilock(api_key="qi_live_...")

        # Create a verification session
        session = client.sessions.create(
            CreateSessionParams(
                applicant_email="john@example.com",
                redirect_url="https://example.com/callback",
            )
        )
        print(session["session_url"])  # Send this to the user

        # Screen a person for AML
        aml = client.aml.screen(ScreenPersonParams(name="John Doe"))

        # Screen a transaction
        tx = client.transactions.screen(
            ScreenTransactionParams(
                transaction_ref="TX-001",
                sender_name="Alice",
                receiver_name="Bob",
                amount=5000,
                currency="USD",
            )
        )

    Args:
        api_key: Your Verilock API key (starts with ``qi_live_`` or ``qi_test_``).
            Falls back to the ``VERILOCK_API_KEY`` environment variable.
        base_url: Base URL of the Verilock API. Defaults to ``https://api.verilock.io``.
        timeout: Request timeout in seconds. Defaults to ``30``.
        max_retries: Maximum automatic retries on 429/5xx errors. Defaults to ``2``.
    """

    sessions: Sessions
    """KYC verification sessions."""

    aml: Aml
    """AML/PEP/sanctions screening."""

    transactions: Transactions
    """Transaction monitoring and screening."""

    biometric: Biometric
    """Biometric face authentication."""

    database: Database
    """Government database validation."""

    face_search: FaceSearch
    """1:N face duplicate detection."""

    wallet: Wallet
    """Crypto wallet compliance screening."""

    credentials: Credentials
    """Reusable KYC credentials."""

    age_verify: AgeVerify
    """Age verification from selfie."""

    def __init__(
        self,
        api_key: Optional[str] = None,
        *,
        base_url: str = "https://api.verilock.io",
        timeout: float = 30,
        max_retries: int = 2,
    ) -> None:
        resolved_key = api_key or os.environ.get("VERILOCK_API_KEY", "")
        if not resolved_key:
            raise ValueError(
                "Missing API key. Pass it as `api_key` or set the VERILOCK_API_KEY "
                "environment variable."
            )

        http = HttpClient(
            api_key=resolved_key,
            base_url=base_url,
            timeout=timeout,
            max_retries=max_retries,
        )

        self.sessions = Sessions(http)
        self.aml = Aml(http)
        self.transactions = Transactions(http)
        self.biometric = Biometric(http)
        self.database = Database(http)
        self.face_search = FaceSearch(http)
        self.wallet = Wallet(http)
        self.credentials = Credentials(http)
        self.age_verify = AgeVerify(http)
        self._http = http

    def close(self) -> None:
        """Close the underlying HTTP connection pool."""
        self._http.close()

    def __enter__(self) -> Verilock:
        return self

    def __exit__(self, *args: object) -> None:
        self.close()


class AsyncVerilock:
    """Async Python client for the Verilock Identity Verification API.

    Example::

        import asyncio
        from verilock import AsyncVerilock
        from verilock.types import CreateSessionParams

        async def main():
            async with AsyncVerilock(api_key="qi_live_...") as client:
                session = await client.sessions.create(
                    CreateSessionParams(
                        applicant_email="john@example.com",
                        redirect_url="https://example.com/callback",
                    )
                )
                print(session["session_url"])

        asyncio.run(main())

    Args:
        api_key: Your Verilock API key (starts with ``qi_live_`` or ``qi_test_``).
            Falls back to the ``VERILOCK_API_KEY`` environment variable.
        base_url: Base URL of the Verilock API. Defaults to ``https://api.verilock.io``.
        timeout: Request timeout in seconds. Defaults to ``30``.
        max_retries: Maximum automatic retries on 429/5xx errors. Defaults to ``2``.
    """

    sessions: AsyncSessions
    """KYC verification sessions."""

    aml: AsyncAml
    """AML/PEP/sanctions screening."""

    transactions: AsyncTransactions
    """Transaction monitoring and screening."""

    biometric: AsyncBiometric
    """Biometric face authentication."""

    database: AsyncDatabase
    """Government database validation."""

    face_search: AsyncFaceSearch
    """1:N face duplicate detection."""

    wallet: AsyncWallet
    """Crypto wallet compliance screening."""

    credentials: AsyncCredentials
    """Reusable KYC credentials."""

    age_verify: AsyncAgeVerify
    """Age verification from selfie."""

    def __init__(
        self,
        api_key: Optional[str] = None,
        *,
        base_url: str = "https://api.verilock.io",
        timeout: float = 30,
        max_retries: int = 2,
    ) -> None:
        resolved_key = api_key or os.environ.get("VERILOCK_API_KEY", "")
        if not resolved_key:
            raise ValueError(
                "Missing API key. Pass it as `api_key` or set the VERILOCK_API_KEY "
                "environment variable."
            )

        http = AsyncHttpClient(
            api_key=resolved_key,
            base_url=base_url,
            timeout=timeout,
            max_retries=max_retries,
        )

        self.sessions = AsyncSessions(http)
        self.aml = AsyncAml(http)
        self.transactions = AsyncTransactions(http)
        self.biometric = AsyncBiometric(http)
        self.database = AsyncDatabase(http)
        self.face_search = AsyncFaceSearch(http)
        self.wallet = AsyncWallet(http)
        self.credentials = AsyncCredentials(http)
        self.age_verify = AsyncAgeVerify(http)
        self._http = http

    async def close(self) -> None:
        """Close the underlying HTTP connection pool."""
        await self._http.close()

    async def __aenter__(self) -> AsyncVerilock:
        return self

    async def __aexit__(self, *args: object) -> None:
        await self.close()
