"""Payments invoices domain — sync and async mixins."""

from __future__ import annotations

from decimal import Decimal
from typing import Any

from ...exceptions import api_error_handler, async_api_error_handler
from ..._api.generated.payments.payments__api__payments.models import (
    PaginatedPaymentListList,
    PaymentCreateRequest,
    PaymentCreateResponse,
    PaymentDetail,
    PaymentStatus,
)


class _PaymentsMixin:
    """Sync payment invoice methods."""

    _api: Any

    @api_error_handler
    def create(
        self,
        *,
        amount_usd: float | Decimal | str,
        currency_code: str,
        project_slug: str,
        customer_id: str,
        description: str | None = None,
        client_reference_id: str | None = None,
        callback_url: str | None = None,
        credential_id: str | None = None,
    ) -> PaymentCreateResponse:
        """Create a new payment invoice."""
        request = PaymentCreateRequest(
            amount_usd=str(amount_usd),
            currency_code=currency_code.upper(),
            project_slug=project_slug,
            customer_id=customer_id,
            description=description,
            client_reference_id=client_reference_id,
            callback_url=callback_url,
            credential_id=credential_id,
        )
        return self._api.payments_create_create(request)

    @api_error_handler
    def list(self, *, page: int = 1, page_size: int = 20, status: str | None = None) -> PaginatedPaymentListList:
        """List payments."""
        return self._api.payments_list(page=page, page_size=page_size)

    @api_error_handler
    def get(self, payment_id: str) -> PaymentDetail:
        """Get payment details."""
        return self._api.payments_retrieve(payment_id)

    @api_error_handler
    def check_status(self, payment_id: str, *, refresh: bool = False) -> PaymentStatus:
        """Check payment status."""
        return self._api.payments_status_retrieve(payment_id, refresh=refresh)

    @api_error_handler
    def cancel(self, payment_id: str) -> PaymentStatus:
        """Cancel a pending payment."""
        return self._api.payments_cancel_create(payment_id)


class _AsyncPaymentsMixin:
    """Async payment invoice methods."""

    _api: Any

    @async_api_error_handler
    async def create(
        self,
        *,
        amount_usd: float | Decimal | str,
        currency_code: str,
        project_slug: str,
        customer_id: str,
        description: str | None = None,
        client_reference_id: str | None = None,
        callback_url: str | None = None,
        credential_id: str | None = None,
    ) -> PaymentCreateResponse:
        """Create a new payment invoice."""
        request = PaymentCreateRequest(
            amount_usd=str(amount_usd),
            currency_code=currency_code.upper(),
            project_slug=project_slug,
            customer_id=customer_id,
            description=description,
            client_reference_id=client_reference_id,
            callback_url=callback_url,
            credential_id=credential_id,
        )
        return await self._api.payments_create_create(request)

    @async_api_error_handler
    async def list(self, *, page: int = 1, page_size: int = 20, status: str | None = None) -> PaginatedPaymentListList:
        """List payments."""
        return await self._api.payments_list(page=page, page_size=page_size)

    @async_api_error_handler
    async def get(self, payment_id: str) -> PaymentDetail:
        """Get payment details."""
        return await self._api.payments_retrieve(payment_id)

    @async_api_error_handler
    async def check_status(self, payment_id: str, *, refresh: bool = False) -> PaymentStatus:
        """Check payment status."""
        return await self._api.payments_status_retrieve(payment_id, refresh=refresh)

    @async_api_error_handler
    async def cancel(self, payment_id: str) -> PaymentStatus:
        """Cancel a pending payment."""
        return await self._api.payments_cancel_create(payment_id)
