"""Payment processor that calls Lambda API for actual payment processing."""

import logging
import requests
from typing import Tuple

logger = logging.getLogger(__name__)


class PaymentProcessor:
    """
    Payment processor that delegates actual payment processing to a Lambda function.
    
    This approach provides:
    - Better security isolation
    - Centralized payment logic
    - Easy scaling and monitoring
    """
    
    def __init__(self, payment_api_endpoint: str):
        """
        Initialize the PaymentProcessor with Lambda API endpoint.
        
        Args:
            payment_api_endpoint: Lambda API Gateway endpoint for payment processing
        """
        self.payment_api_endpoint = payment_api_endpoint
        logger.info("PaymentProcessor initialized with Lambda API endpoint")
    
    def process(self, card_number: str, cvv: str, amount: int, 
               currency: str, cardholder_name: str, exp_month: int, exp_year: int,
               transaction_id: str) -> Tuple[bool, str]:
        """
        Process payment by calling Lambda API endpoint.
        
        Args:
            card_number: Decrypted card number
            cvv: Decrypted CVV
            amount: Payment amount in cents
            currency: Currency code (e.g., 'usd')
            cardholder_name: Name on card
            exp_month: Card expiry month
            exp_year: Card expiry year
            transaction_id: Unique transaction ID for reference
            
        Returns:
            Tuple of (success, message)
        """
        logger.info(f"Processing payment via Lambda API: {amount} {currency} for {cardholder_name}")
        
        try:
            # Prepare payment data for Lambda API
            payment_data = {
                "transaction_id": transaction_id,  # For reference only
                "card_number": card_number,
                "cvv": cvv,
                "exp_month": exp_month,
                "exp_year": exp_year,
                "amount": amount,
                "currency": currency.lower(),
                "cardholder_name": cardholder_name
            }
            
            # Call Lambda API endpoint
            response = requests.post(
                f"{self.payment_api_endpoint}",
                json=payment_data,
                headers={
                    "Content-Type": "application/json"
                },
                timeout=30  # 30 second timeout
            )
            
            if response.status_code == 200:
                result = response.json()
                if result.get("success"):
                    success_msg = result.get("message", f"Payment succeeded - ID: {result.get('payment_id', transaction_id)}")
                    logger.info(f"Payment succeeded: {success_msg}")
                    return True, success_msg
                else:
                    error_msg = result.get("message", "Payment failed")
                    logger.warning(f"Payment failed: {error_msg}")
                    return False, error_msg
            
            elif response.status_code == 400:
                # Bad request - validation error
                result = response.json()
                error_msg = result.get("message", "Invalid payment data")
                logger.error(f"Payment validation error: {error_msg}")
                return False, error_msg
            
            elif response.status_code == 429:
                # Rate limited
                error_msg = "Payment service rate limited - please retry"
                logger.warning(f"Rate limited: {error_msg}")
                return False, error_msg
            
            else:
                # Other HTTP errors
                error_msg = f"Payment service error - HTTP {response.status_code}"
                logger.error(f"HTTP error: {error_msg}")
                return False, error_msg
                
        except requests.exceptions.Timeout:
            error_msg = "Payment service timeout - please retry"
            logger.error(f"Timeout error: {error_msg}")
            return False, error_msg
            
        except requests.exceptions.ConnectionError:
            error_msg = "Payment service unavailable - please retry"
            logger.error(f"Connection error: {error_msg}")
            return False, error_msg
            
        except requests.exceptions.RequestException as e:
            error_msg = f"Payment service request failed: {str(e)}"
            logger.error(f"Request error: {error_msg}")
            return False, error_msg
            
        except Exception as e:
            error_msg = f"Unexpected error in payment processing: {str(e)}"
            logger.error(f"Unexpected error: {error_msg}")
            return False, error_msg