import { NextResponse } from 'next/server';
import { withErrorHandler } from '@server/middleware/withErrorHandler';
import { withAuth, requireSection, requireSectionAny, AuthedRequest } from '@server/middleware/withAuth';
import { withValidationAuthed } from '@server/middleware/withValidation';
import { createBranchSchema } from '@server/validators/branches.validator';
import { listBranches, createBranch } from '@server/services/branches.service';
import { isBranchPinned, requireOwner } from '@server/utils/branch-access';
import { requirePlanFeature, getPlanLimits } from '@server/utils/features';
import { AppError } from '@server/errors';
import { db } from '@server/db/drizzle';
import { sql } from 'drizzle-orm';

export const GET = withErrorHandler(
  withAuth(async (req: AuthedRequest) => {
    const { restaurantId } = req.session;
    // Branch list data is required by every sidebar section for navigation
    // (branch picker), scoping, and supporting UI. We explicitly enumerate
    // all justified consumers so that the guard remains fail-closed while
    // avoiding over-restriction. Any staff with at least one active section
    // has a legitimate need to know which branches their restaurant has.
    await requireSectionAny(req, [
      'branches', 'storefront', 'telephone', 'whatsapp', 'chat_widget',
      'ai_config', 'knowledge_base', 'conversations', 'orders', 'reservations',
      'menu', 'customers', 'loyalty', 'marketing', 'gift_cards', 'coupons',
      'staff', 'analytics', 'settings',
    ]);
    const url = new URL(req.url);
    const activeOnly = url.searchParams.get('active') === 'true';
    // Hard-pinned staff get a single-row list; owners always see all branches
    // so the topbar picker keeps working.
    const scope = isBranchPinned(req.session) ? req.session.pinnedBranchId ?? null : null;
    const branches = await listBranches(restaurantId!, activeOnly, scope);
    return NextResponse.json({ branches });
  })
);

export const POST = withErrorHandler(
  withAuth(
    withValidationAuthed(createBranchSchema, async (req) => {
      requireOwner(req.session, 'create branches');
      const restaurantId = req.session.restaurantId!;

      // Count existing active branches
      const { rows } = await db.execute(sql`
        SELECT COUNT(*) AS count FROM branches
        WHERE restaurant_id = ${restaurantId} AND is_active = true
      `);
      const branchCount = parseInt((rows[0] as { count: string }).count, 10);

      // Adding a 2nd+ branch requires the multi_branch feature
      if (branchCount >= 1) {
        await requirePlanFeature(restaurantId, 'multi_branch');
      }

      // Enforce the numeric max_branches plan limit
      const limits = await getPlanLimits(restaurantId);
      if (limits.max_branches !== null && branchCount >= limits.max_branches) {
        throw new AppError(
          `Your plan allows a maximum of ${limits.max_branches} branch${limits.max_branches === 1 ? '' : 'es'}. Upgrade your plan to add more.`,
          402,
          'PLAN_LIMIT_EXCEEDED'
        );
      }

      const branch = await createBranch(restaurantId, req.parsedBody as Record<string, unknown>);
      return NextResponse.json({ branch }, { status: 201 });
    })
  )
);
