import { NextResponse } from 'next/server';
import { z } from 'zod';

import { withAuth, withPermission } from '@/lib/api/helpers';
import { parseBody } from '@/lib/api/route-helpers';
import {
  findOrphanInterests,
  listStages,
  saveStages,
  type ResidentialStage,
} from '@/lib/services/residential-stages.service';
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
import { errorResponse } from '@/lib/errors';

export const GET = withAuth(
  withPermission('residential_interests', 'view', async (_req, ctx) => {
    try {
      await assertResidentialModuleEnabled(ctx.portId);
      const stages = await listStages(ctx.portId);
      const orphans = await findOrphanInterests(
        ctx.portId,
        stages.map((s) => s.id),
      );
      return NextResponse.json({ data: { stages, orphans } });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);

const stageSchema: z.ZodType<ResidentialStage> = z.object({
  id: z
    .string()
    .min(1)
    .max(50)
    .regex(/^[a-z0-9_]+$/, 'lowercase letters, digits, underscore only'),
  label: z.string().min(1).max(80),
  terminal: z.enum(['won', 'lost']).nullable(),
});

const putSchema = z.object({
  stages: z.array(stageSchema).min(1),
  reassignments: z.record(z.string(), z.string()).optional(),
  force: z.boolean().optional(),
});

export const PUT = withAuth(
  withPermission('admin', 'manage_settings', async (req, ctx) => {
    try {
      await assertResidentialModuleEnabled(ctx.portId);
      const body = await parseBody(req, putSchema);
      await saveStages(
        {
          portId: ctx.portId,
          stages: body.stages,
          reassignments: body.reassignments,
          force: body.force,
        },
        {
          userId: ctx.userId,
          portId: ctx.portId,
          ipAddress: ctx.ipAddress,
          userAgent: ctx.userAgent,
        },
      );
      return new NextResponse(null, { status: 204 });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);
