"""Payments currencies 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 (
    Currency,
    CurrencyEstimateResponse,
    PaginatedCurrencyList,
)


class _CurrenciesMixin:
    """Sync currencies methods."""

    _api: Any

    @api_error_handler
    def list_currencies(self, *, page: int = 1, page_size: int = 50) -> PaginatedCurrencyList:
        """List available currencies for payments."""
        return self._api.currencies_list(page=page, page_size=page_size)

    @api_error_handler
    def get_currency(self, code: str) -> Currency:
        """Get currency details."""
        return self._api.currencies_retrieve(code.upper())

    @api_error_handler
    def get_deposit_estimate(
        self,
        currency_code: str,
        amount_usd: float | Decimal | str,
    ) -> CurrencyEstimateResponse:
        """Get deposit estimate for a currency."""
        return self._api.currencies_estimate_retrieve(
            code=currency_code.upper(),
            amount_usd=float(amount_usd),
        )

    @api_error_handler
    def get_withdrawal_estimate(
        self,
        currency_code: str,
        amount_usd: float | Decimal | str,
    ) -> CurrencyEstimateResponse:
        """Get withdrawal estimate for a currency."""
        return self._api.currencies_withdrawal_estimate_retrieve(
            code=currency_code.upper(),
            amount_usd=float(amount_usd),
        )


class _AsyncCurrenciesMixin:
    """Async currencies methods."""

    _api: Any

    @async_api_error_handler
    async def list_currencies(self, *, page: int = 1, page_size: int = 50) -> PaginatedCurrencyList:
        """List available currencies for payments."""
        return await self._api.currencies_list(page=page, page_size=page_size)

    @async_api_error_handler
    async def get_currency(self, code: str) -> Currency:
        """Get currency details."""
        return await self._api.currencies_retrieve(code.upper())

    @async_api_error_handler
    async def get_deposit_estimate(
        self,
        currency_code: str,
        amount_usd: float | Decimal | str,
    ) -> CurrencyEstimateResponse:
        """Get deposit estimate for a currency."""
        return await self._api.currencies_estimate_retrieve(
            code=currency_code.upper(),
            amount_usd=float(amount_usd),
        )

    @async_api_error_handler
    async def get_withdrawal_estimate(
        self,
        currency_code: str,
        amount_usd: float | Decimal | str,
    ) -> CurrencyEstimateResponse:
        """Get withdrawal estimate for a currency."""
        return await self._api.currencies_withdrawal_estimate_retrieve(
            code=currency_code.upper(),
            amount_usd=float(amount_usd),
        )
