/**
 * Billing Checkout REST endpoint — pre-built Stripe Checkout Session.
 *
 * POST   /billing/checkout   — create Stripe Checkout Session (any auth)
 *
 * This is a higher-level wrapper over /stripe/checkout with:
 *  - Zod-validated input (priceId OR plan)
 *  - Tax collection support
 *  - Customer email pre-fill
 *  - Arbitrary metadata passthrough
 */

import type { FastifyInstance } from 'fastify';
import type Stripe from 'stripe';
import { getRequestProductId } from '../../lib/request-context.js';
import { BadRequestError } from '../../lib/errors.js';
import { getStripeForProduct, getPriceIds } from '../../lib/stripe.js';
import { BillingCheckoutSchema, type BillingCheckoutResponse } from './types.js';

export async function billingCheckoutRoutes(app: FastifyInstance) {
  app.post('/billing/checkout', async (req, reply) => {
    const parsed = BillingCheckoutSchema.safeParse(req.body);
    if (!parsed.success) {
      throw new BadRequestError(parsed.error.issues.map(i => i.message).join('; '));
    }

    const input = parsed.data;
    const productId = getRequestProductId(req);
    const stripe = getStripeForProduct(productId);

    // Resolve priceId: explicit priceId takes precedence, otherwise look up by plan
    let priceId = input.priceId;
    if (!priceId && input.plan) {
      const priceIds = getPriceIds();
      priceId = priceIds[input.plan];
      if (!priceId) throw new BadRequestError(`No price configured for plan: ${input.plan}`);
    }
    if (!priceId) throw new BadRequestError('Could not resolve a Stripe priceId');

    const params: Stripe.Checkout.SessionCreateParams = {
      mode: 'subscription',
      line_items: [{ price: priceId, quantity: 1 }],
      success_url: input.successUrl,
      cancel_url: input.cancelUrl,
      metadata: {
        userId: input.userId,
        productId,
        ...(input.plan && { plan: input.plan }),
        ...(input.metadata ?? {}),
      },
      ...(input.trialDays &&
        input.trialDays > 0 && {
          subscription_data: { trial_period_days: input.trialDays },
        }),
      ...(input.promoCode && { allow_promotion_codes: true }),
      ...(input.collectTax && { automatic_tax: { enabled: true } }),
      ...(input.customerEmail && { customer_email: input.customerEmail }),
    };

    const session = await stripe.checkout.sessions.create(params);

    const response: BillingCheckoutResponse = {
      sessionId: session.id,
      url: session.url,
    };

    reply.code(201);
    return response;
  });
}
