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

import { withAuth, withPermission } from '@/lib/api/helpers';
import { parseBody } from '@/lib/api/route-helpers';
import { db } from '@/lib/db';
import { websiteSubmissions } from '@/lib/db/schema/website-submissions';
import { createAuditLog } from '@/lib/audit';
import { errorResponse, NotFoundError } from '@/lib/errors';

const bodySchema = z.object({
  state: z.enum(['open', 'assigned', 'converted', 'dismissed']),
});

/**
 * Mutate the triage state of a single inquiry. Used by the inbox row
 * actions: Mark assigned / Mark resolved (converted) / Dismiss.
 *
 * The 'converted' state is set automatically by the new-client-from-
 * inquiry flow once the operator submits the prefilled form; this
 * endpoint accepts it explicitly too so an operator can mark
 * already-handled submissions caught up retrospectively.
 */
export const PATCH = withAuth(
  withPermission('admin', 'view_audit_log', async (req, ctx, params) => {
    try {
      const id = params.id;
      if (!id) throw new NotFoundError('submission');

      const { state } = await parseBody(req, bodySchema);

      const [updated] = await db
        .update(websiteSubmissions)
        .set({
          triageState: state,
          triagedAt: new Date(),
          triagedBy: ctx.userId,
        })
        .where(and(eq(websiteSubmissions.id, id), eq(websiteSubmissions.portId, ctx.portId)))
        .returning({
          id: websiteSubmissions.id,
          triageState: websiteSubmissions.triageState,
          triagedAt: websiteSubmissions.triagedAt,
        });

      if (!updated) throw new NotFoundError('submission');

      void createAuditLog({
        userId: ctx.userId,
        portId: ctx.portId,
        action: 'update',
        entityType: 'website_submission',
        entityId: id,
        fieldChanged: 'triageState',
        newValue: { triageState: state },
        ipAddress: ctx.ipAddress,
        userAgent: ctx.userAgent,
      });

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