// Stripe billing for the $10/mo membership.
// POST /api/billing/checkout -> a Stripe Checkout Session URL (subscription mode).
// GET  /api/billing/portal   -> a Stripe Billing Portal URL (manage/cancel).
// The webhook that flips subscriptions active lives in routes/webhooks_stripe.js
// (mounted with a raw body before express.json in server.js).
import { Router } from 'express';
import Stripe from 'stripe';
import { config, stripeReady } from '../config.js';
import { requireAuth } from '../middleware/auth.js';
import { queryOne } from '../db/client.js';
import { HttpError } from '../middleware/error.js';

const router = Router();
const stripe = config.stripe.secretKey ? new Stripe(config.stripe.secretKey) : null;

// Most recent stripe_customer_id we have on file for this user (if any).
async function customerIdFor(userId) {
  const row = await queryOne(
    `SELECT stripe_customer_id FROM subscriptions
     WHERE user_id = ? AND stripe_customer_id IS NOT NULL
     ORDER BY updated_at DESC LIMIT 1`,
    [userId]
  );
  return row ? row.stripe_customer_id : null;
}

// Start a subscription checkout. Member must be signed in first.
router.post('/checkout', requireAuth, async (req, res, next) => {
  try {
    if (!stripe || !stripeReady()) {
      throw new HttpError(503, 'billing_unavailable', 'Checkout is being switched on. Check back shortly.');
    }
    const user = await queryOne(`SELECT id, email FROM users WHERE id = ?`, [req.auth.userId]);
    if (!user) throw new HttpError(404, 'not_found', 'Account not found');

    const customerId = await customerIdFor(user.id);
    const session = await stripe.checkout.sessions.create({
      mode: 'subscription',
      line_items: [{ price: config.stripe.priceId, quantity: 1 }],
      client_reference_id: user.id,
      ...(customerId ? { customer: customerId } : { customer_email: user.email }),
      allow_promotion_codes: true,
      billing_address_collection: 'auto',
      metadata: { user_id: user.id },
      subscription_data: { metadata: { user_id: user.id } },
      success_url: config.memberAppUrl + '/library.html?welcome=1',
      cancel_url: config.memberAppUrl + '/account.html',
    });
    res.json({ url: session.url });
  } catch (err) {
    next(err);
  }
});

// Open the Stripe billing portal so members manage or cancel themselves.
router.get('/portal', requireAuth, async (req, res, next) => {
  try {
    if (!stripe) throw new HttpError(503, 'billing_unavailable', 'Billing is not available yet');
    const customerId = await customerIdFor(req.auth.userId);
    if (!customerId) throw new HttpError(400, 'no_customer', 'No billing account on file yet');
    const portal = await stripe.billingPortal.sessions.create({
      customer: customerId,
      return_url: config.memberAppUrl + '/account.html',
    });
    res.json({ url: portal.url });
  } catch (err) {
    next(err);
  }
});

export default router;
