"""
Stripe Checkout helpers for ecommerce.
"""
import stripe
from django.conf import settings
from django.urls import reverse


def _get_stripe_secret_key(tenant=None):
    """
    The Stripe secret key for this tenant, from Settings and nowhere else.

    Called without a tenant it reads the master row, the same resolver every
    other credential uses. It used to call SiteSettings.load(None), which
    returns the orphaned null-tenant row and reported no key while a key was
    plainly saved.
    """
    from apps.pages.api_keys import _site
    site = _site(tenant)
    # No borrowing. This used to fall back to any other tenant's key, which
    # meant a site with no Stripe account of its own took payments into
    # somebody else's. A tenant with no key has no payments, and the
    # checkout says so. No environment fallback either.
    return (site.stripe_secret_key or '') if site else ''


def _get_stripe_webhook_secret(tenant=None):
    """Webhook signing secret from Settings. Never .env."""
    from apps.pages.api_keys import _site
    site = _site(tenant)
    return (site.stripe_webhook_secret or '') if site else ''


def create_checkout_session(order, request, mode='payment'):
    """
    Create a Stripe Checkout session for an Order.
    `mode` — 'payment' for one-time, 'deposit' uses order.items deposit amounts.
    Returns the Stripe session object.
    """
    tenant = getattr(order, 'tenant', None)
    stripe.api_key = _get_stripe_secret_key(tenant)
    line_items = []

    for item in order.items.all():
        # Determine the charge amount for this item
        if mode == 'deposit' and item.product and item.product.has_deposit:
            amount = int(item.product.deposit_amount * 100)  # pence
            name = f'{item.product_name} (Deposit)'
        else:
            amount = int(item.unit_price * 100)
            name = item.product_name

        if item.domain_name:
            name = f'{item.domain_name} ({item.registration_years} yr)'

        line_items.append({
            'price_data': {
                'currency': 'gbp',
                'unit_amount': amount,
                'product_data': {
                    'name': name,
                    'description': item.custom_description or None,
                },
            },
            'quantity': item.quantity,
        })

    success_url = request.build_absolute_uri(
        reverse('shop_order_success') + f'?session_id={{CHECKOUT_SESSION_ID}}'
    )
    cancel_url = request.build_absolute_uri(reverse('shop_cart'))

    session = stripe.checkout.Session.create(
        payment_method_types=['card'],
        line_items=line_items,
        mode='payment',
        success_url=success_url,
        cancel_url=cancel_url,
        customer_email=order.customer_email,
        metadata={
            'order_id': str(order.id),
            'order_number': order.order_number,
            'is_deposit': 'true' if mode == 'deposit' else 'false',
        },
    )
    return session


def create_balance_payment_session(order, request):
    """
    Create a Stripe Checkout session for paying the remaining balance on an order.
    """
    stripe.api_key = _get_stripe_secret_key(getattr(order, 'tenant', None))
    balance = order.balance_due
    session = stripe.checkout.Session.create(
        payment_method_types=['card'],
        line_items=[{
            'price_data': {
                'currency': 'gbp',
                'unit_amount': int(balance * 100),
                'product_data': {
                    'name': f'Balance Payment — Order #{order.order_number}',
                },
            },
            'quantity': 1,
        }],
        mode='payment',
        success_url=request.build_absolute_uri(
            reverse('shop_order_success') + f'?session_id={{CHECKOUT_SESSION_ID}}&order_number={order.order_number}'
        ),
        cancel_url=request.build_absolute_uri(
            reverse('shop_order_detail', args=[order.order_number])
        ),
        customer_email=order.customer_email,
        metadata={
            'order_id': str(order.id),
            'order_number': order.order_number,
            'is_deposit': 'false',
            'is_balance_payment': 'true',
        },
    )
    return session


def retrieve_session(session_id):
    return stripe.checkout.Session.retrieve(session_id)


def construct_webhook_event(payload, sig_header):
    return stripe.Webhook.construct_event(
        payload, sig_header, _get_stripe_webhook_secret()
    )
