import { NextResponse } from 'next/server';
import { withErrorHandler } from '@server/middleware/withErrorHandler';
import {
  getRestaurantForWidget,
  getWidgetSettings,
  createWidgetConversation,
  signWidgetToken,
} from '@server/services/widget.service';
import { withWidgetCors, widgetOptionsResponse } from '../_cors';
import { hasPlanFeature, getPlanLimits } from '@server/utils/features';
import { getUsage } from '@server/services/billing.service';
import { initDatabase } from '@server/db/init';
import { withRateLimit, getClientIp } from '@server/middleware/withRateLimit';

export async function OPTIONS() { return widgetOptionsResponse(); }

export const POST = withWidgetCors(
  withRateLimit(
    [
      {
        scope: 'widget:start:ip',
        limit: 20,
        windowMs: 60 * 60 * 1000,
        keyOf: (req) => getClientIp(req),
      },
      {
        scope: 'widget:start:ip:short',
        limit: 5,
        windowMs: 60 * 1000,
        keyOf: (req) => getClientIp(req),
      },
    ],
    withErrorHandler(async (req: Request) => {
      const body = await req.json().catch(() => ({}));
      const { restaurantId, customerName } = body as { restaurantId?: string; customerName?: string };

      if (!restaurantId) {
        return NextResponse.json({ error: 'restaurantId is required' }, { status: 400 });
      }

      await initDatabase();

      // Enforce chat_agent plan feature before creating a conversation
      const [chatEnabled, limits] = await Promise.all([
        hasPlanFeature(restaurantId, 'chat_agent'),
        getPlanLimits(restaurantId),
      ]);

      if (!chatEnabled) {
        return NextResponse.json(
          { error: 'Chat agent is not included in this restaurant\'s current plan.' },
          { status: 402 }
        );
      }

      // Enforce conversations_per_month cap using the canonical billing usage source
      if (limits.conversations_per_month !== null) {
        const usage = await getUsage(restaurantId);
        if (usage.conversations >= limits.conversations_per_month) {
          return NextResponse.json(
            {
              error: `Monthly conversation limit of ${limits.conversations_per_month} reached. Please upgrade your plan.`,
              code: 'PLAN_LIMIT_EXCEEDED',
            },
            { status: 402 }
          );
        }
      }

      const restaurant = await getRestaurantForWidget(restaurantId);
      if (!restaurant) {
        return NextResponse.json({ error: 'Restaurant not found or inactive' }, { status: 404 });
      }

      const settings = await getWidgetSettings(restaurantId);
      if (!settings?.is_enabled) {
        return NextResponse.json({ error: 'Chat widget is not enabled for this restaurant' }, { status: 403 });
      }

      const conversation = await createWidgetConversation(
        restaurantId,
        customerName || 'Website Visitor',
        settings.agent_id ?? null
      );
      const sessionToken = signWidgetToken(restaurantId, conversation.id);

      return NextResponse.json({
        sessionToken,
        conversationId: conversation.id,
        restaurant: {
          id: restaurant.id,
          name: restaurant.name,
          logo_url: restaurant.logo_url,
        },
        settings,
      });
    })
  )
);
