"""
Abstract base class for payment provider clients.

All provider implementations (Payrix, Stub, future processors) must
implement this interface so that calling code in services is fully
decoupled from the underlying payment processor.
"""
from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Any, Dict


class PaymentProviderClient(ABC):
    """
    Abstract payment provider client.

    Implementations must be stateless and safe to instantiate on every
    request (the factory in __init__.py returns a fresh instance each call).
    """

    @abstractmethod
    async def get_token_details(self, token: str, merchant_id: int = 0) -> Dict[str, Any]:
        """
        Retrieve details for a previously generated payment token.

        Args:
            token: The provider token/id produced by the payment iframe.
            merchant_id: Internal merchant id; used by some providers for
                routing/logging.  Defaults to 0 (unknown).

        Returns:
            A dict containing at minimum:
                - provider_payment_method_id (str): The token id to store.
            May also include: provider, brand, last4,
            exp_month, exp_year.
        """

    @abstractmethod
    async def submit_charge(
        self,
        *,
        amount: float,
        currency: str,
        customer_id: int,
        merchant_id: int,
        token: str,
        payment_method_type: str = "card",
        capture: bool = True,
        **kwargs: Any,
    ) -> Dict[str, Any]:
        """
        Submit a payment charge to the provider.

        Args:
            amount: Transaction amount (same unit/scale as stored in DB).
            currency: ISO-4217 currency code, e.g. "usd".
            customer_id: Internal customer id.
            merchant_id: Internal merchant id.
            token: The provider payment method token.
            payment_method_type: "card" or "ach".
            capture: Whether to capture immediately (sale) or only authorise.
            **kwargs: Provider-specific optional parameters.

        Returns:
            A dict with keys:
                - transaction_id (str | None): Provider transaction identifier.
                - status (str): Normalised status string, e.g. "succeeded".
                - amount (int | float): Amount as echoed/confirmed by provider.
                - currency (str): Currency as echoed/confirmed by provider.
                - raw_response (dict): Full raw response body from provider.
        """
