import { NextRequest, NextResponse } from 'next/server';
import Stripe from 'stripe';
import { createStripeClient } from '@/lib/stripe/server';
import { sql } from '@/lib/db/postgres';
import { logApiError } from '@/lib/api/security';

const PLAN_BY_PRICE: Record<string, string> = {
  [process.env.STRIPE_PRO_PRICE_ID ?? '']: 'pro',
  [process.env.STRIPE_PRO_PLUS_PRICE_ID ?? '']: 'pro_plus',
  [process.env.STRIPE_BUSINESS_PRICE_ID ?? '']: 'business',
};

export async function POST(req: NextRequest) {
  const body = await req.text();
  const sig = req.headers.get('stripe-signature')!;
  const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;

  if (!webhookSecret) {
    return NextResponse.json({ error: 'Stripe webhook is not configured' }, { status: 503 });
  }

  let event: Stripe.Event;
  try {
    const stripe = createStripeClient();
    event = stripe.webhooks.constructEvent(body, sig, webhookSecret);
  } catch {
    return NextResponse.json({ error: 'Invalid signature' }, { status: 400 });
  }

  try {
    if (event.type === 'customer.subscription.created' || event.type === 'customer.subscription.updated') {
      const sub = event.data.object as Stripe.Subscription;
      const priceId = sub.items.data[0]?.price.id ?? '';
      const plan = PLAN_BY_PRICE[priceId] ?? 'free';
      const status =
        sub.status === 'active' ? 'active'
        : sub.status === 'trialing' ? 'trial'
        : sub.status === 'past_due' ? 'past_due'
        : 'canceled';
      const periodStart = sub.items.data[0]?.current_period_start
        ? new Date(sub.items.data[0].current_period_start * 1000)
        : null;
      const periodEnd = sub.items.data[0]?.current_period_end
        ? new Date(sub.items.data[0].current_period_end * 1000)
        : null;

      await sql`
        UPDATE user_subscriptions
        SET
          plan = ${plan},
          status = ${status},
          stripe_subscription_id = ${sub.id},
          current_period_start = ${periodStart},
          current_period_end = ${periodEnd}
        WHERE stripe_customer_id = ${sub.customer as string}
      `;
    }

    if (event.type === 'customer.subscription.deleted') {
      const sub = event.data.object as Stripe.Subscription;
      await sql`
        UPDATE user_subscriptions
        SET plan = 'free', status = 'canceled', stripe_subscription_id = NULL
        WHERE stripe_customer_id = ${sub.customer as string}
      `;
    }

    if (event.type === 'checkout.session.completed') {
      const session = event.data.object as Stripe.Checkout.Session;
      if (session.mode === 'payment' && session.metadata?.design_id && session.metadata?.user_id) {
        await sql`
          INSERT INTO note_design_purchases (user_id, design_id, design_type, amount_cents, stripe_payment_intent_id)
          VALUES (
            ${session.metadata.user_id},
            ${session.metadata.design_id},
            ${session.metadata.design_type || 'cover'},
            ${session.amount_total ?? 0},
            ${typeof session.payment_intent === 'string' ? session.payment_intent : null}
          )
          ON CONFLICT (user_id, design_id) DO NOTHING
        `;
      }
    }
  } catch (error) {
    logApiError('Stripe webhook DB error', error);
    return NextResponse.json({ error: 'Internal error' }, { status: 500 });
  }

  return NextResponse.json({ received: true });
}
