"""X402 agent settlement and verification resource."""

from typing import Any, Dict, Optional

from ..client import AsyncHttpClient, HttpClient
from ..types import X402PayloadDto, X402SubmitResponseDto, X402VerifyResponseDto

BASE_PATH = "/api/v1/payments/agent"


class X402Resource:
    """Synchronous x402 resource for agent-based settlement and verification."""

    def __init__(self, client: HttpClient) -> None:
        self._client = client

    def settle(
        self,
        *,
        scheme: str,
        chain: str,
        asset: str,
        payload: Dict[str, Any],
        session_reference: Optional[str] = None,
    ) -> X402SubmitResponseDto:
        """Settle an x402 payment via signed authorization.

        Submits a signed EIP-3009 or Permit2 payload to execute a
        gasless token transfer on-chain.

        Args:
            scheme: Settlement scheme ("eip3009" or "permit2").
            chain: Blockchain network ("base", "arbitrum", "bsc").
            asset: Crypto asset ("USDC" or "USDT").
            payload: Signed payment payload dict containing ``signature``
                and either ``authorization`` or ``permit2Authorization``.
            session_reference: Optional checkout session reference to
                validate against.

        Returns:
            Settlement result with transaction hash and details.
        """
        body: Dict[str, Any] = {
            "scheme": scheme,
            "chain": chain,
            "asset": asset,
            "payload": payload,
        }
        if session_reference is not None:
            body["sessionReference"] = session_reference

        return self._client.request("POST", f"{BASE_PATH}/settle", json_body=body)

    def verify(
        self,
        *,
        scheme: str,
        chain: str,
        asset: str,
        payload: Dict[str, Any],
        session_reference: Optional[str] = None,
    ) -> X402VerifyResponseDto:
        """Verify an x402 payment payload without executing it.

        Runs validation checks on the signed authorization payload
        to confirm it is well-formed and will succeed.

        Args:
            scheme: Settlement scheme ("eip3009" or "permit2").
            chain: Blockchain network ("base", "arbitrum", "bsc").
            asset: Crypto asset ("USDC" or "USDT").
            payload: Signed payment payload dict.
            session_reference: Optional checkout session reference to
                validate against.

        Returns:
            Verification result with ``valid`` flag and individual checks.
        """
        body: Dict[str, Any] = {
            "scheme": scheme,
            "chain": chain,
            "asset": asset,
            "payload": payload,
        }
        if session_reference is not None:
            body["sessionReference"] = session_reference

        return self._client.request("POST", f"{BASE_PATH}/verify", json_body=body)


class AsyncX402Resource:
    """Asynchronous x402 resource for agent-based settlement and verification."""

    def __init__(self, client: AsyncHttpClient) -> None:
        self._client = client

    async def settle(
        self,
        *,
        scheme: str,
        chain: str,
        asset: str,
        payload: Dict[str, Any],
        session_reference: Optional[str] = None,
    ) -> X402SubmitResponseDto:
        """Settle an x402 payment via signed authorization (async)."""
        body: Dict[str, Any] = {
            "scheme": scheme,
            "chain": chain,
            "asset": asset,
            "payload": payload,
        }
        if session_reference is not None:
            body["sessionReference"] = session_reference

        return await self._client.request("POST", f"{BASE_PATH}/settle", json_body=body)

    async def verify(
        self,
        *,
        scheme: str,
        chain: str,
        asset: str,
        payload: Dict[str, Any],
        session_reference: Optional[str] = None,
    ) -> X402VerifyResponseDto:
        """Verify an x402 payment payload without executing it (async)."""
        body: Dict[str, Any] = {
            "scheme": scheme,
            "chain": chain,
            "asset": asset,
            "payload": payload,
        }
        if session_reference is not None:
            body["sessionReference"] = session_reference

        return await self._client.request("POST", f"{BASE_PATH}/verify", json_body=body)
