"""
Payment Provider Interface
Abstract base class for payment provider implementations
Allows easy swapping of payment SDKs (Stripe, PayPal, etc.)
"""

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


class PaymentProvider(ABC):
    """
    Abstract Payment Provider Interface
    Define all required methods for payment processing
    """
    
    @abstractmethod
    async def create_customer(
        self,
        email: str,
        name: Optional[str] = None,
        metadata: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """Create a customer in the payment provider"""
        pass
    
    @abstractmethod
    async def attach_payment_method(
        self,
        payment_method_id: str,
        customer_id: str
    ) -> Dict[str, Any]:
        """Attach a payment method to a customer"""
        pass
    
    @abstractmethod
    async def set_default_payment_method(
        self,
        customer_id: str,
        payment_method_id: str
    ) -> Dict[str, Any]:
        """Set the default payment method for a customer"""
        pass
    
    @abstractmethod
    async def create_setup_intent_for_verification(
        self,
        customer_id: str,
        payment_method_id: str,
        metadata: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """Create a SetupIntent for payment method verification (3DS support)"""
        pass
    
    @abstractmethod
    async def verify_setup_intent_status(
        self,
        setup_intent_id: str
    ) -> Dict[str, Any]:
        """Verify the status of a SetupIntent"""
        pass
    
    @abstractmethod
    async def create_subscription_with_verified_payment(
        self,
        customer_id: str,
        price_id: str,
        payment_method_id: str,
        trial_period_days: Optional[int] = None,
        billing_cycle_anchor: Optional[Any] = None,
        metadata: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """Create a subscription with a verified payment method

        Args:
            billing_cycle_anchor: Can be int (Unix timestamp), "now", or "unchanged"
        """
        pass
    
    @abstractmethod
    async def create_setup_intent(self) -> Dict[str, Any]:
        """Create a basic SetupIntent"""
        pass
    
    @abstractmethod
    async def get_setup_intent(
        self,
        setup_intent_id: str
    ) -> Any:
        """Get SetupIntent details"""
        pass
    
    @abstractmethod
    async def create_payment_intent(
        self,
        amount: float,
        currency: str,
        customer_id: str,
        payment_method_id: str
    ) -> Dict[str, Any]:
        """Create a PaymentIntent for one-time payments"""
        pass
    
    @abstractmethod
    async def complete_subscription_after_setup_intent(
        self,
        setup_intent_id: str
    ) -> Dict[str, Any]:
        """Complete subscription creation after SetupIntent verification"""
        pass
    
    @abstractmethod
    async def cancel_subscription(
        self,
        subscription_id: str
    ) -> Dict[str, Any]:
        """Cancel a subscription"""
        pass
    
    @abstractmethod
    async def update_payment_method(
        self,
        customer_id: str,
        payment_method_id: str
    ) -> Dict[str, Any]:
        """Update customer's payment method"""
        pass
    
    @abstractmethod
    async def update_subscription(
        self,
        subscription_id: str,
        new_price_id: str
    ) -> Dict[str, Any]:
        """Update subscription price"""
        pass
    
    @abstractmethod
    async def get_subscription(
        self,
        subscription_id: str
    ) -> Dict[str, Any]:
        """Get subscription details"""
        pass
    
    @abstractmethod
    async def get_customer_payment_method(
        self,
        customer_id: str
    ) -> Dict[str, Any]:
        """Get customer's payment method"""
        pass
    
    @abstractmethod
    async def get_invoices(
        self,
        customer_id: str
    ) -> Dict[str, Any]:
        """Get customer invoices"""
        pass