import { NextResponse } from 'next/server';
import { withErrorHandler, RouteContext } from '@server/middleware/withErrorHandler';
import { withRateLimit, getClientIp, checkRateLimit } from '@server/middleware/withRateLimit';
import { getStorefrontProfile } from '@server/services/storefront.service';
import { hasPlanFeature } from '@server/utils/features';
import { getSettings } from '@server/services/loyalty.service';

/**
 * Public storefront helper: check whether this branch has loyalty enabled and
 * return program-level settings (earn rate, redeem rate, minimum threshold).
 *
 * This endpoint intentionally performs NO customer lookup and returns NO
 * customer-specific data. All customer-specific loyalty handling (balance
 * check, tier, redemption preview, and application) is done server-side
 * during order creation where the customer's phone is already required.
 *
 * Returning per-customer fields (found/not-found, balance, tier, progress)
 * to anonymous callers would enable unauthenticated phone-number enumeration
 * and account profiling. The cart UX can use the generic program settings
 * returned here to display program details without revealing customer data.
 */
export const POST = withRateLimit(
  [
    // IP bucket: defense-in-depth (header is user-injectable but raises the bar).
    {
      scope: 'storefront:loyalty:ip',
      limit: 20,
      windowMs: 5 * 60 * 1000,
      keyOf: (req) => getClientIp(req),
    },
  ],
  withErrorHandler(async (req: Request, ctx: RouteContext) => {
    const { restaurantSlug, branchSlug } = await ctx.params;

    // Per-branch bucket: server-controlled key, not attacker-injectable.
    const branchKey = `${restaurantSlug}:${branchSlug}`;
    const branchLimit = checkRateLimit('storefront:loyalty:branch', branchKey, 100, 5 * 60 * 1000);
    if (!branchLimit.allowed) {
      return NextResponse.json(
        { error: 'Too many requests. Please slow down and try again later.', code: 'RATE_LIMITED', retryAfter: branchLimit.retryAfterSec },
        { status: 429, headers: { 'Retry-After': String(branchLimit.retryAfterSec ?? 300) } }
      );
    }

    // Consume and discard request body to avoid confusing clients that send one.
    await req.json().catch(() => null);

    const profile = await getStorefrontProfile(restaurantSlug, branchSlug);
    if (!profile || !profile.feature_enabled) {
      return NextResponse.json({ enabled: false });
    }
    const restaurantId = profile.branch.restaurant_id as string;
    const planEnabled = await hasPlanFeature(restaurantId, 'loyalty');
    if (!planEnabled) return NextResponse.json({ enabled: false });

    // Return only program-level settings — no customer lookup, no per-customer data.
    const settings = await getSettings(restaurantId);
    return NextResponse.json({
      enabled: true,
      settings: {
        earn_mode: settings.earn_mode,
        earn_rate: settings.earn_rate,
        min_redeem_points: settings.min_redeem_points,
        redeem_points_per_unit: settings.redeem_points_per_unit,
        redeem_unit_value: settings.redeem_unit_value,
      },
    });
  })
);
