from __future__ import annotations

from typing import TYPE_CHECKING, Any

from gamma23.types import ExecuteResult, PaymentRequest

if TYPE_CHECKING:
    from gamma23.client import Gamma23


class Payments:
    """Create and execute payment requests."""

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

    def create(
        self,
        *,
        amount: float,
        merchant: str,
        domain: str | None = None,
        category: str | None = None,
        reason: str | None = None,
        evidence_links: list[str] | None = None,
        idempotency_key: str | None = None,
    ) -> PaymentRequest:
        """Create a new payment request.

        Args:
            amount: Payment amount.
            merchant: Merchant name.
            domain: Merchant domain for verification.
            category: Spending category.
            reason: Human-readable justification for the payment.
            evidence_links: URLs supporting the payment rationale.
            idempotency_key: Optional idempotency key to prevent duplicates.

        Returns:
            The created :class:`PaymentRequest`.
        """
        body: dict[str, Any] = {
            "amount": amount,
            "merchant": merchant,
        }
        if domain is not None:
            body["domain"] = domain
        if category is not None:
            body["category"] = category
        if reason is not None:
            body["reason"] = reason
        if evidence_links is not None:
            body["evidence_links"] = evidence_links

        headers: dict[str, str] = {}
        if idempotency_key is not None:
            headers["Idempotency-Key"] = idempotency_key

        data = self._client._request(
            "POST",
            "/api/v1/payments",
            json=body,
            headers=headers or None,
        )
        return PaymentRequest.from_dict(data)

    def execute(
        self,
        request_id: str,
        *,
        spend_token: str,
        mode: str | None = None,
    ) -> ExecuteResult:
        """Execute an approved payment request.

        Args:
            request_id: The payment request identifier.
            spend_token: The spend token received upon approval.
            mode: Optional execution mode (e.g. ``"live"``, ``"sandbox"``).

        Returns:
            An :class:`ExecuteResult` with transaction details.
        """
        body: dict[str, Any] = {"spend_token": spend_token}
        if mode is not None:
            body["mode"] = mode

        data = self._client._request(
            "POST",
            f"/api/v1/payments/{request_id}/execute",
            json=body,
        )
        return ExecuteResult.from_dict(data)
