"""
Payme payment gateway client.
This is a thin wrapper that provides a clean interface but delegates to internal implementation.
"""
import logging
from typing import Dict, Any, Optional, Union

from paytechuz.core.http import HttpClient
from paytechuz.core.base import BasePaymentGateway
from paytechuz.core.utils import handle_exceptions

from paytechuz.gateways.payme.cards import PaymeCards
from paytechuz.gateways.payme.receipts import PaymeReceipts
from paytechuz.gateways.payme.constants import PaymeNetworks
from paytechuz.gateways.payme.internal import PaymeGatewayInternal


logger = logging.getLogger(__name__)


class PaymeGateway(BasePaymentGateway):
    """
    Payme payment gateway implementation.

    This class provides methods for interacting with the Payme payment gateway,
    including creating payments, checking payment status, and canceling payments.
    """

    def __init__(
        self,
        payme_id: str,
        payme_key: Optional[str] = None,
        fallback_id: Optional[str] = None,
        is_test_mode: bool = False,
        **kwargs
    ):
        """
        Initialize the Payme gateway.

        Args:
            payme_id: Payme merchant ID
            payme_key: Payme merchant key for authentication
            fallback_id: Fallback merchant ID
            is_test_mode: Whether to use the test environment
            **kwargs: Additional arguments (ignored, for backward compatibility)
        """
        super().__init__(is_test_mode)
        self.payme_id = payme_id
        self.payme_key = payme_key
        self.fallback_id = fallback_id

        # Set the API URL based on the environment
        url = PaymeNetworks.TEST_NET if is_test_mode else PaymeNetworks.PROD_NET

        # Initialize HTTP client
        self.http_client = HttpClient(base_url=url)

        # Initialize components
        self.cards = PaymeCards(http_client=self.http_client, payme_id=payme_id)
        self.receipts = PaymeReceipts(
            http_client=self.http_client,
            payme_id=payme_id,
            payme_key=payme_key
        )

        # Initialize internal implementation
        self._internal = PaymeGatewayInternal(
            payme_id=payme_id,
            payme_key=payme_key,
            fallback_id=fallback_id,
            is_test_mode=is_test_mode,
            http_client=self.http_client,
            cards=self.cards,
            receipts=self.receipts
        )

    def generate_pay_link(
        self,
        id: Union[int, str],
        amount: Union[int, float, str],
        return_url: str,
        account_field_name: str = "order_id"
    ) -> str:
        """
        Generate a payment link for a specific order.

        Parameters
        ----------
        id : Union[int, str]
            Unique identifier for the account/order.
        amount : Union[int, float, str]
            Payment amount in som.
        return_url : str
            URL to redirect after payment completion.
        account_field_name : str, optional
            Field name for account identifier (default: "order_id").

        Returns
        -------
        str
            Payme checkout URL with encoded parameters.

        References
        ----------
        https://developer.help.paycom.uz/initsializatsiya-platezhey/
        """
        return self._internal.generate_pay_link(id, amount, return_url, account_field_name)

    async def generate_pay_link_async(
        self,
        id: Union[int, str],
        amount: Union[int, float, str],
        return_url: str,
        account_field_name: str = "order_id"
    ) -> str:
        """
        Async version of generate_pay_link.

        Parameters
        ----------
        id : Union[int, str]
            Unique identifier for the account/order.
        amount : Union[int, float, str]
            Payment amount in som.
        return_url : str
            URL to redirect after payment completion.
        account_field_name : str, optional
            Field name for account identifier (default: "order_id").

        Returns
        -------
        str
            Payme checkout URL with encoded parameters.
        """
        return self.generate_pay_link(id, amount, return_url, account_field_name)

    @handle_exceptions
    def create_payment(
        self,
        id: Union[int, str],
        amount: Union[int, float, str],
        return_url: str = "",
        account_field_name: str = "order_id"
    ) -> str:
        """
        Create a payment using Payme.

        Args:
            id: Account or order ID
            amount: Payment amount in som
            return_url: Return URL after payment (default: "")
            account_field_name: Field name for account ID (default: "order_id")

        Returns:
            str: Payme payment URL
        """
        return self.generate_pay_link(id, amount, return_url, account_field_name)

    @handle_exceptions
    async def create_payment_async(
        self,
        id: Union[int, str],
        amount: Union[int, float, str],
        return_url: str = "",
        account_field_name: str = "order_id"
    ) -> str:
        """
        Async version of create_payment.

        Args:
            id: Account or order ID
            amount: Payment amount in som
            return_url: Return URL after payment (default: "")
            account_field_name: Field name for account ID (default: "order_id")

        Returns:
            str: Payme payment URL
        """
        return await self.generate_pay_link_async(id, amount, return_url, account_field_name)

    def check_payment(self, transaction_id: str) -> Dict[str, Any]:
        """
        Check payment status using Payme receipts.

        Args:
            transaction_id: The receipt ID to check

        Returns:
            Dict containing payment status and details
        """
        return self._internal.check_payment(transaction_id)

    def cancel_payment(
        self,
        transaction_id: str,
        reason: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        Cancel payment using Payme receipts.

        Args:
            transaction_id: The receipt ID to cancel
            reason: Optional reason for cancellation

        Returns:
            Dict containing cancellation status and details
        """
        return self._internal.cancel_payment(transaction_id, reason)
