"""Native Stripe webhook verification and platform event translation."""

from __future__ import annotations

import hashlib
import hmac
import os
import time
from typing import Any

from sqlalchemy import func, select

from bridge_platform.billing.webhooks import BillingWebhookError, SIGNATURE_TOLERANCE_SECONDS
from config.control_plane import get_control_plane_session
from bridge_platform.tenants.models import BillingProductMapping


SUPPORTED_STRIPE_EVENTS = {
    "customer.subscription.created",
    "customer.subscription.updated",
    "customer.subscription.deleted",
}


def verify_stripe_signature(raw_body: bytes, signature_header: str) -> None:
    secret = os.getenv("STRIPE_WEBHOOK_SECRET")
    if not secret:
        raise BillingWebhookError("Stripe webhook is not configured")
    values: dict[str, list[str]] = {}
    for part in signature_header.split(","):
        key, separator, value = part.strip().partition("=")
        if separator:
            values.setdefault(key, []).append(value)
    try:
        timestamp = int(values["t"][0])
    except (KeyError, IndexError, ValueError):
        raise BillingWebhookError("Invalid Stripe-Signature header") from None
    if abs(time.time() - timestamp) > SIGNATURE_TOLERANCE_SECONDS:
        raise BillingWebhookError("Stripe webhook timestamp is outside the allowed window")
    expected = hmac.new(
        secret.encode("utf-8"),
        str(timestamp).encode("ascii") + b"." + raw_body,
        hashlib.sha256,
    ).hexdigest()
    if not any(hmac.compare_digest(expected, candidate) for candidate in values.get("v1", [])):
        raise BillingWebhookError("Invalid Stripe webhook signature")


def translate_stripe_event(payload: dict[str, Any]) -> dict[str, Any]:
    stripe_type = str(payload.get("type") or "")
    if stripe_type not in SUPPORTED_STRIPE_EVENTS:
        return {
            "id": payload.get("id"),
            "type": f"stripe.ignored.{stripe_type or 'unknown'}",
            "data": {},
        }
    stripe_object = ((payload.get("data") or {}).get("object") or {})
    if not isinstance(stripe_object, dict):
        raise BillingWebhookError("Stripe event object is invalid")
    status = "canceled" if stripe_type.endswith(".deleted") else str(stripe_object.get("status") or "")
    metadata = stripe_object.get("metadata") or {}
    items = (((stripe_object.get("items") or {}).get("data")) or [])
    price = ((items[0].get("price") or {}) if items and isinstance(items[0], dict) else {})
    return {
        "id": payload.get("id"),
        "type": f"subscription.{status}",
        "data": {
            "tenant_id": metadata.get("tenant_id"),
            "customer_id": stripe_object.get("customer"),
            "subscription_id": stripe_object.get("id"),
            "price_id": price.get("id"),
            "status": status,
            "current_period_start": stripe_object.get("current_period_start"),
            "current_period_end": stripe_object.get("current_period_end"),
            "cancel_at_period_end": stripe_object.get("cancel_at_period_end", False),
        },
    }


def stripe_readiness() -> dict[str, Any]:
    secret_key = os.getenv("STRIPE_SECRET_KEY", "")
    publishable_key = os.getenv("STRIPE_PUBLISHABLE_KEY", "")
    webhook_secret = os.getenv("STRIPE_WEBHOOK_SECRET", "")
    with get_control_plane_session() as session:
        price_count = int(session.execute(
            select(func.count(BillingProductMapping.mapping_id)).where(
                BillingProductMapping.provider == "stripe",
                BillingProductMapping.is_active.is_(True),
            )
        ).scalar_one())
    return {
        "provider": "stripe",
        "mode": "test" if secret_key.startswith("sk_test_") or publishable_key.startswith("pk_test_") else "unconfigured",
        "secret_key_configured": bool(secret_key),
        "publishable_key_configured": bool(publishable_key),
        "webhook_secret_configured": bool(webhook_secret),
        "ready_for_webhooks": bool(webhook_secret),
        "ready_for_checkout": bool(secret_key and publishable_key),
        "prices_configured": price_count > 0,
        "configured_price_count": price_count,
        "live_payments_enabled": False,
    }
