"""
Mandatum Payment Gateway Wrappers

Wrap popular payment SDKs with Mandatum authorization.
The agent must get approval before any payment goes through.

Usage (Razorpay):
    from mandatum import Mandatum
    from mandatum.payments import MandatumRazorpay

    m = Mandatum(api_key="mdt_live_...")
    pay = MandatumRazorpay(razorpay_client, m, "agt_abc123")
    result = pay.create_order(amount=50000, currency="INR")
    if result["allowed"]:
        print("Payment created!", result["order"])

Usage (Stripe):
    from mandatum.payments import MandatumStripe

    pay = MandatumStripe(stripe, m, "agt_abc123")
    result = pay.create_payment_intent(amount=5000, currency="usd")
"""


class MandatumRazorpay:
    """Wraps Razorpay with Mandatum spending limits."""

    def __init__(self, razorpay_client, mandatum_client, agent_id: str):
        self.razorpay = razorpay_client
        self.mandatum = mandatum_client
        self.agent_id = agent_id

    def create_order(self, amount: int, currency: str = "INR",
                     description: str = None, notes: dict = None, **kwargs) -> dict:
        """
        Create a Razorpay order — checks Mandatum limits first.

        Args:
            amount: Amount in paise (smallest currency unit)
            currency: Currency code (default: INR)
            description: Human-readable description
            notes: Razorpay notes dict

        Returns:
            dict with 'allowed', 'order' (if allowed), 'reason' (if blocked)
        """
        amount_in_rupees = amount / 100

        approval = self.mandatum.agents.spend(self.agent_id, {
            "amount": amount_in_rupees,
            "currency": currency,
            "vendor": "razorpay",
            "category": "payment",
            "description": description or f"Razorpay order: {currency} {amount_in_rupees}",
        })

        if not approval.get("allowed"):
            return {
                "allowed": False,
                "reason": approval.get("reason"),
                "event_id": approval.get("eventId"),
                "spending": approval.get("spending"),
            }

        try:
            order = self.razorpay.order.create({
                "amount": amount,
                "currency": currency,
                "notes": {**(notes or {}), "mandatum_event_id": approval["eventId"]},
                **kwargs,
            })
            return {
                "allowed": True,
                "order": order,
                "event_id": approval["eventId"],
                "spending": approval.get("spending"),
            }
        except Exception as e:
            return {
                "allowed": True,
                "payment_failed": True,
                "error": str(e),
                "event_id": approval["eventId"],
            }


class MandatumStripe:
    """Wraps Stripe with Mandatum spending limits."""

    def __init__(self, stripe_client, mandatum_client, agent_id: str):
        self.stripe = stripe_client
        self.mandatum = mandatum_client
        self.agent_id = agent_id

    def create_payment_intent(self, amount: int, currency: str = "usd",
                               description: str = None, metadata: dict = None, **kwargs) -> dict:
        """
        Create a Stripe PaymentIntent — checks Mandatum limits first.

        Args:
            amount: Amount in cents (smallest currency unit)
            currency: Currency code (default: usd)
        """
        amount_in_major = amount / 100

        approval = self.mandatum.agents.spend(self.agent_id, {
            "amount": amount_in_major,
            "currency": currency.upper(),
            "vendor": "stripe",
            "category": "payment",
            "description": description or f"Stripe payment: {currency.upper()} {amount_in_major}",
        })

        if not approval.get("allowed"):
            return {
                "allowed": False,
                "reason": approval.get("reason"),
                "event_id": approval.get("eventId"),
            }

        try:
            intent = self.stripe.PaymentIntent.create(
                amount=amount,
                currency=currency,
                description=description,
                metadata={**(metadata or {}), "mandatum_event_id": approval["eventId"]},
                **kwargs,
            )
            return {
                "allowed": True,
                "payment_intent": intent,
                "event_id": approval["eventId"],
                "spending": approval.get("spending"),
            }
        except Exception as e:
            return {
                "allowed": True,
                "payment_failed": True,
                "error": str(e),
                "event_id": approval["eventId"],
            }
