from typing import Literal
import paypalrestsdk
from pydantic import BaseModel
from fastapi import HTTPException
import logging


# Model for payment request body
class PaymentRequest(BaseModel):
    user_id: str
    credit_amount: Literal[10, 50, 100]
    currency: Literal["USD", "EUR", "CHF"]  
    description: str = "Purchase of credits"


# Payment handler class for managing PayPal payments
class PaymentHandler:

    payment_id: str

    def __init__(self, transaction_details: PaymentRequest):
        self.details = transaction_details
        self.logger = logging.getLogger(__name__)

    # Only support purchase of credit 'bundles': 10, 50 or 100 credits worth of trip generation
    def fetch_price(self) -> float:
        """
        Fetches the price of credits in the specified currency.
        """
        result = self.supabase.table("prices").select("credit_amount").eq("currency", self.details.currency).single().execute()
        if result.data:
            return result.data.get("price")
        else:
            self.logger.error(f"Unsupported currency: {self.details.currency}")
            return None

    def create_paypal_payment(self) -> str:
        """
        Creates a PayPal payment and returns the approval URL.
        """
        price = self.fetch_price()
        payment = paypalrestsdk.Payment({
            "intent": "sale",
            "payer": {
                "payment_method": "paypal"
            },
            "transactions": [{
                "amount": {
                    "total": f"{price:.2f}",
                    "currency": self.details.currency
                },
                "description": self.details.description
            }],
            "redirect_urls": {
                "return_url": "http://localhost:8000/payment/success",
                "cancel_url": "http://localhost:8000/payment/cancel"
            }
        })

        if payment.create():
            self.logger.info("Payment created successfully")
            self.payment_id = payment.id

            # Get the approval URL and return it for the user to approve
            for link in payment.links:
                if link.rel == "approval_url":
                    return link.href
        else:
            self.logger.error(f"Failed to create payment: {payment.error}")
            raise HTTPException(status_code=500, detail="Payment creation failed")
