import { NextResponse } from 'next/server';
import { withErrorHandler } from '@server/middleware/withErrorHandler';
import { withAuth, AuthedRequest } from '@server/middleware/withAuth';
import { ValidationError } from '@server/errors';
import { getStripeClientFromDb } from '@server/lib/stripe';
import { getGatewayConfig } from '@server/services/gateway.service';
import { db } from '@server/db/drizzle';
import { sql } from 'drizzle-orm';
import { initDatabase } from '@server/db/init';
import { childLogger } from '@server/logger';

const log = childLogger('route.billing.promo-validate');

export const POST = withErrorHandler(
  withAuth(async (req: AuthedRequest) => {
    await initDatabase();
    let _body: Awaited<ReturnType<typeof req.json>>;
    try {
      _body = await req.json();
    } catch {
      throw new ValidationError('Request body must be valid JSON');
    }
    const { promoCode, planId, billingCycle } = _body;

    if (!promoCode?.trim()) {
      return NextResponse.json({ error: 'promoCode is required', code: 'VALIDATION_ERROR' }, { status: 400 });
    }

    const cfg = await getGatewayConfig();
    if (!cfg.stripeActive) {
      return NextResponse.json({ error: 'Stripe is not configured', code: 'GATEWAY_NOT_CONFIGURED' }, { status: 503 });
    }
    if (!cfg.stripePromoCodesEnabled) {
      return NextResponse.json({ error: 'Promo codes are not enabled', code: 'PROMO_DISABLED' }, { status: 400 });
    }

    const stripe = await getStripeClientFromDb();

    const { rows } = await db.execute(sql`
      SELECT p.price_monthly, p.price_annual, pp.price_monthly AS pp_monthly, pp.price_annual AS pp_annual
      FROM plans p
      LEFT JOIN plan_prices pp ON pp.plan_id = p.id AND pp.currency_code = ${cfg.stripeCurrency.toUpperCase()}
      WHERE p.id = ${planId}
      LIMIT 1
    `);
    const row = rows[0] as {
      price_monthly: string; price_annual: string;
      pp_monthly: string | null; pp_annual: string | null;
    } | undefined;

    if (!row) {
      return NextResponse.json({ error: 'Plan not found', code: 'NOT_FOUND' }, { status: 404 });
    }

    const isAnnual = billingCycle === 'annual';
    const baseMonthly = parseFloat(row.pp_monthly ?? row.price_monthly) || 0;
    const baseAnnual = parseFloat(row.pp_annual ?? row.price_annual) || 0;
    const originalAmount = isAnnual ? baseAnnual : baseMonthly;
    const currency = cfg.stripeCurrency.toLowerCase();

    try {
      const promoCodes = await stripe.promotionCodes.list({
        code: promoCode.trim(),
        active: true,
        limit: 1,
        expand: ['data.promotion.coupon'],
      });

      if (promoCodes.data.length === 0) {
        return NextResponse.json({ valid: false, error: 'Invalid or expired promo code' });
      }

      const promoCodeObj = promoCodes.data[0];
      const couponField = promoCodeObj.promotion?.coupon;
      const coupon = (typeof couponField === 'object' && couponField !== null) ? couponField : null;

      let discountedAmount = originalAmount;
      let discountDescription = '';

      if (coupon?.amount_off) {
        const amountOff = coupon.amount_off / 100;
        discountedAmount = Math.max(0, originalAmount - amountOff);
        discountDescription = `-${currency.toUpperCase()} ${amountOff.toFixed(2)} off`;
      } else if (coupon?.percent_off) {
        discountedAmount = originalAmount * (1 - coupon.percent_off / 100);
        discountDescription = `-${coupon.percent_off}% off`;
      }

      if (coupon?.duration === 'once') {
        discountDescription += ' (first billing)';
      } else if (coupon?.duration === 'repeating' && coupon.duration_in_months) {
        discountDescription += ` (${coupon.duration_in_months} months)`;
      }

      log.info({ planId, billingCycle, promoCode: promoCode.trim() }, 'promo code validated');

      return NextResponse.json({
        valid: true,
        promotionCodeId: promoCodeObj.id,
        originalAmount,
        discountedAmount,
        currency,
        discountDescription,
      });
    } catch (err) {
      log.error({ err }, 'promo-validate: Stripe error');
      return NextResponse.json({ error: 'Failed to validate promo code', code: 'PROMO_ERROR' }, { status: 400 });
    }
  })
);
