"""Thin Stripe wrapper for checkout and webhook handling.

Checkout session creation talks to Stripe; webhook parsing verifies the HMAC
signature when a webhook secret is configured, and falls back to plain JSON in
dev/test so the plan-change flow can be exercised without Stripe.
"""

from __future__ import annotations

import json

import stripe

from legate.config import get_settings


class StripeError(Exception):
    """Raised when a Stripe call or webhook verification fails."""


def create_checkout_session(
    *, workspace_id: str, plan: str, success_url: str, cancel_url: str
) -> str:
    settings = get_settings()
    if not settings.stripe_api_key:
        raise StripeError("STRIPE_API_KEY is not configured")
    stripe.api_key = settings.stripe_api_key
    try:
        session = stripe.checkout.Session.create(
            mode="subscription",
            success_url=success_url,
            cancel_url=cancel_url,
            metadata={"workspace_id": workspace_id, "plan": plan},
            line_items=[{"price": f"price_{plan}", "quantity": 1}],
        )
    except Exception as exc:  # stripe raises a variety of errors
        raise StripeError(str(exc)) from exc
    if not session.url:
        raise StripeError("Stripe did not return a checkout URL")
    return session.url


def parse_event(payload: bytes, signature: str | None) -> dict:
    settings = get_settings()
    if settings.stripe_webhook_secret:
        try:
            event = stripe.Webhook.construct_event(
                payload, signature or "", settings.stripe_webhook_secret
            )
            return dict(event)
        except Exception as exc:
            raise StripeError(f"invalid webhook signature: {exc}") from exc
    # Dev/test: no secret configured -> trust the parsed body.
    try:
        return json.loads(payload)
    except (ValueError, TypeError) as exc:
        raise StripeError("invalid webhook payload") from exc
