import { NextResponse } from 'next/server';
import { z } from 'zod';
import { and, eq, inArray, isNull } from 'drizzle-orm';

import { withAuth, withPermission } from '@/lib/api/helpers';
import { parseBody } from '@/lib/api/route-helpers';
import { errorResponse } from '@/lib/errors';
import { db } from '@/lib/db';
import { berths } from '@/lib/db/schema/berths';

const checkSchema = z.object({
  mooringNumbers: z
    .array(z.string().regex(/^[A-Z]+\d+$/, 'Invalid mooring format'))
    .min(1)
    .max(500),
});

/**
 * POST /api/v1/berths/check-duplicates
 *
 * Pre-flight duplicate check for the bulk-add wizard. Given an array of
 * candidate mooring numbers, returns which of them already exist as
 * non-archived berths in the port. Lets the wizard flag and prune
 * collisions before the user fills out Step 2 dimensions, instead of
 * surfacing the constraint violation at submit time.
 *
 * Format validation mirrors the CLAUDE.md canonical (`^[A-Z]+\d+$`).
 * Archived berths are excluded - bulk-add re-using a previously-archived
 * mooring number is a legitimate flow.
 *
 * Permission gating: `berths.import` (same scope as bulk-add itself).
 */
export const POST = withAuth(
  withPermission('berths', 'import', async (req, ctx) => {
    try {
      const { mooringNumbers } = await parseBody(req, checkSchema);
      // Dedup the input first so a wizard passing the same number twice
      // doesn't cause an over-counted match. The wizard generates a
      // contiguous range so dups in the input are unusual, but cheap to guard.
      const unique = Array.from(new Set(mooringNumbers));

      const existing = await db
        .select({ mooringNumber: berths.mooringNumber })
        .from(berths)
        .where(
          and(
            eq(berths.portId, ctx.portId),
            inArray(berths.mooringNumber, unique),
            isNull(berths.archivedAt),
          ),
        );

      const duplicates = existing.map((r) => r.mooringNumber);
      return NextResponse.json({
        data: {
          duplicates,
          checked: unique.length,
        },
      });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);
