import { NextRequest, NextResponse } from 'next/server';
import { stripe, PLANS, type PlanKey } from '@/lib/stripe';
import {
  createLicence,
  deactivateLicenceBySubscription,
  reactivateLicenceBySubscription,
  resetQuotaOnRenewal,
  getLicenceBySubscription,
} from '@/lib/supabase';

async function sendLicenceEmail(email: string, key: string, planName: string) {
  const apiKey = process.env.RESEND_API_KEY;
  if (!apiKey) return;

  await fetch('https://api.resend.com/emails', {
    method:  'POST',
    headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({
      from:    'NoteToQuote <noreply@notetoquote.com>',
      to:      [email],
      subject: 'Votre clé de licence NoteToQuote',
      html: `
        <h2>Bienvenue sur NoteToQuote !</h2>
        <p>Votre abonnement <strong>${planName}</strong> est actif.</p>
        <p>Votre clé de licence :</p>
        <pre style="background:#f4f4f4;padding:1rem;border-radius:8px;font-size:1.2rem;letter-spacing:0.05em">${key}</pre>
        <p>Renseignez cette clé dans Dolibarr → Configuration → NoteToQuote → Configurer.</p>
        <p>Des questions ? Répondez à cet email.</p>
      `,
    }),
  }).catch(console.error);
}

export async function POST(req: NextRequest) {
  const body      = await req.text();
  const signature = req.headers.get('stripe-signature') ?? '';

  let event;
  try {
    event = stripe.webhooks.constructEvent(body, signature, process.env.STRIPE_WEBHOOK_SECRET!);
  } catch {
    return NextResponse.json({ error: 'invalid_signature' }, { status: 400 });
  }

  switch (event.type) {
    case 'checkout.session.completed': {
      const session = event.data.object as unknown as {
        subscription:   string;
        customer_email: string;
        customer:       string;
        metadata:       Record<string, string>;
      };
      const subscriptionId = session.subscription;
      const email          = session.customer_email;
      const plan           = session.metadata?.plan as PlanKey;

      if (!subscriptionId || !email || !plan || !PLANS[plan]) break;

      // Use Stripe's billing period end as quota reset date
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      const sub     = await stripe.subscriptions.retrieve(subscriptionId) as any;
      const resetAt = new Date(sub.current_period_end * 1000).toISOString();

      const { key } = await createLicence(
        email,
        plan,
        PLANS[plan].quota,
        session.customer,
        subscriptionId,
        resetAt,
      );

      await sendLicenceEmail(email, key, PLANS[plan].name);
      break;
    }

    case 'customer.subscription.updated': {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      const sub = event.data.object as any as {
        id: string;
        status: string;
        current_period_end: number;
      };

      const licence = await getLicenceBySubscription(sub.id);
      if (!licence) break;

      if (sub.status === 'active' || sub.status === 'trialing') {
        const newResetAt = new Date(sub.current_period_end * 1000).toISOString();
        if (newResetAt > licence.reset_at) {
          // Billing period renewed — reset quota and update period end
          await resetQuotaOnRenewal(sub.id, newResetAt);
        } else {
          await reactivateLicenceBySubscription(sub.id);
        }
      } else if (sub.status === 'canceled' || sub.status === 'unpaid') {
        await deactivateLicenceBySubscription(sub.id);
      }
      break;
    }

    case 'customer.subscription.deleted': {
      const sub = event.data.object as { id: string };
      await deactivateLicenceBySubscription(sub.id);
      break;
    }
  }

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