"""Main PaymentClient class for interacting with the Payelink Payment API."""

import os

from dotenv import load_dotenv

from payelink_agent_pay.config import ClientConfig
from payelink_agent_pay.errors import (
    InsufficientFundsError,
    PaymentAPIError,
    PaymentValidationError,
)
from payelink_agent_pay.models import (
    WalletTransferRequest,
    WalletTransferResponse,
)
from payelink_agent_pay.transport import HTTPTransport


class PaymentClient:
    """Client for interacting with the Payelink Payment API."""

    def __init__(
        self,
        api_key: str | None = None,
        base_url: str | None = None,
        timeout: float = 30.0,
        max_retries: int = 3,
        retry_delay: float = 1.0,
        verify_ssl: bool = True,
    ):
        """Initialize the PaymentClient.

        Args:
            api_key: API key for authentication. If not provided, will be loaded from
                PAYELINK_KEY environment variable (supports .env file).
            base_url: Base URL for the payment API (optional)
            timeout: Request timeout in seconds
            max_retries: Maximum number of retry attempts
            retry_delay: Delay between retries in seconds
            verify_ssl: Whether to verify SSL certificates

        Raises:
            ValueError: If api_key is not provided and PAYELINK_KEY is not found in
                environment variables or .env file.
        """
        # Load API key from parameter or environment
        if api_key is None:
            load_dotenv()
            api_key = os.getenv("PAYELINK_KEY")
            if api_key is None:
                raise ValueError(
                    "API key is required. Either provide 'api_key' parameter or set "
                    "PAYELINK_KEY environment variable (supports .env file)."
                )

        self.config = ClientConfig(
            api_key=api_key,
            base_url=base_url or "http://127.0.0.1:8000/v1",
            timeout=timeout,
            max_retries=max_retries,
            retry_delay=retry_delay,
            verify_ssl=verify_ssl,
        )
        self.transport = HTTPTransport(self.config)

    def wallet_transfer(self, request: WalletTransferRequest) -> WalletTransferResponse:
        """Transfer funds between wallets.

        Args:
            request: Wallet transfer request with from_wallet_key, to_wallet_key, and value

        Returns:
            Wallet transfer response with transaction details

        Raises:
            PaymentAPIError: If the transfer fails or other API errors
            InsufficientFundsError: If there are insufficient funds
            PaymentValidationError: If the request is invalid
        """
        try:
            data = self.transport.post(
                "/wallets/transfer", json=request.model_dump(exclude_none=True)
            )
            return WalletTransferResponse(**data)
        except PaymentAPIError as e:
            if e.status_code == 400:
                raise PaymentValidationError(e.message) from e
            if e.status_code == 402:
                raise InsufficientFundsError(e.message) from e
            raise

    def close(self) -> None:
        """Close the HTTP client and release resources."""
        self.transport.close()

    def __enter__(self) -> "PaymentClient":
        """Context manager entry."""
        return self

    def __exit__(self, exc_type, exc_val, exc_tb) -> None:
        """Context manager exit."""
        self.close()
