import { NextRequest, NextResponse } from 'next/server';

import { withAuth, withPermission } from '@/lib/api/helpers';
import { errorResponse, NotFoundError } from '@/lib/errors';
import { updateFieldSchema } from '@/lib/validators/custom-fields';
import { updateDefinition, deleteDefinition } from '@/lib/services/custom-fields.service';

export const PATCH = withAuth(
  withPermission('admin', 'manage_custom_fields', async (req: NextRequest, ctx, params) => {
    try {
      const { fieldId } = params;
      if (!fieldId) throw new NotFoundError('Custom field');

      // Read raw body before parsing so we can inspect `fieldType`
      // (the schema strips it; the service rejects any change). Using
      // req.json() directly here is intentional - parseBody would lose
      // the raw view we need for the mutation-attempt detection below.
      const body = (await req.json()) as Record<string, unknown>;
      const data = updateFieldSchema.parse(body);

      // Pass raw body too so service can detect fieldType mutation attempts
      const updated = await updateDefinition(
        ctx.portId,
        fieldId,
        ctx.userId,
        { ...data, ...(body.fieldType !== undefined && { fieldType: body.fieldType }) },
        {
          userId: ctx.userId,
          portId: ctx.portId,
          ipAddress: ctx.ipAddress,
          userAgent: ctx.userAgent,
        },
      );

      return NextResponse.json({ data: updated });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);

export const DELETE = withAuth(
  withPermission('admin', 'manage_custom_fields', async (_req: NextRequest, ctx, params) => {
    try {
      const { fieldId } = params;
      if (!fieldId) throw new NotFoundError('Custom field');

      const result = await deleteDefinition(ctx.portId, fieldId, ctx.userId, {
        userId: ctx.userId,
        portId: ctx.portId,
        ipAddress: ctx.ipAddress,
        userAgent: ctx.userAgent,
      });

      return NextResponse.json({ data: result });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);
