import { NextResponse } from 'next/server';
import { z } from 'zod';
import { withErrorHandler } from '@server/middleware/withErrorHandler';
import { withAuth, requireSection } from '@server/middleware/withAuth';
import { withValidationAuthed } from '@server/middleware/withValidation';
import { requirePlanFeature } from '@server/utils/features';
import { previewRedeem, previewEarn } from '@server/services/loyalty.service';

const previewSchema = z.object({
  customer_id: z.string().uuid(),
  points_to_redeem: z.number().int().min(0).optional(),
  subtotal: z.number().min(0),
  channel: z.string().optional(),
  delivery_type: z.string().optional(),
  item_count: z.number().int().min(0).optional(),
});

export const POST = withErrorHandler(
  withAuth(
    withValidationAuthed(previewSchema, async (req) => {
      const { restaurantId } = req.session;
      await requireSection(req, 'loyalty');
      await requirePlanFeature(restaurantId!, 'loyalty');
      const b = req.parsedBody;
      const redeem = await previewRedeem({
        restaurantId: restaurantId!,
        customerId: b.customer_id,
        pointsRequested: b.points_to_redeem ?? 0,
        subtotal: b.subtotal,
      });
      // Earning is calculated against the post-redemption subtotal — points
      // do not earn on themselves.
      const earnSubtotal = Math.max(0, b.subtotal - Number(redeem.discount_amount || 0));
      const earn = await previewEarn({
        restaurantId: restaurantId!,
        customerId: b.customer_id,
        channel: b.channel ?? null,
        deliveryType: b.delivery_type ?? null,
        subtotal: earnSubtotal,
        itemCount: b.item_count ?? 0,
      });
      return NextResponse.json({ redeem, earn });
    })
  )
);
