'use server';

import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
import { z } from 'zod';
import { getDb } from '@pintrush/db';
import { actionError, actionOk, CONFLICT_MESSAGE, type ActionResult } from '@/components/host/action-result';
import { requireAdmin } from '@/lib/auth/session';
import { adminAudit } from '../../_lib/audit';
import { LEAD_STATUSES } from '../../_lib/constants';

export async function setLeadStatus(_prev: ActionResult, formData: FormData): Promise<ActionResult> {
  const { admin } = await requireAdmin();
  const parsed = z
    .object({ leadId: z.uuid(), status: z.enum(LEAD_STATUSES), expectedVersion: z.coerce.number().int().min(0) })
    .safeParse({ leadId: formData.get('leadId'), status: formData.get('status'), expectedVersion: formData.get('expectedVersion') });
  if (!parsed.success) return actionError('Pick a status.');
  const { leadId, status, expectedVersion } = parsed.data;
  const outcome = await getDb().$transaction(async (tx) => {
    const lead = await tx.pilotLead.findUnique({ where: { id: leadId }, select: { status: true } });
    if (!lead) return 'missing' as const;
    const { count } = await tx.pilotLead.updateMany({ where: { id: leadId, version: expectedVersion }, data: { status, version: { increment: 1 } } });
    if (count === 0) return 'conflict' as const;
    await adminAudit(tx, admin.id, 'admin.lead.status_changed', { leadId, from: lead.status, to: status });
    return 'ok' as const;
  });
  if (outcome === 'missing') return actionError('That lead no longer exists.');
  if (outcome === 'conflict') return actionError(CONFLICT_MESSAGE);
  revalidatePath('/admin/leads', 'layout');
  return actionOk(`Status set to ${status.toLowerCase()}.`);
}

/**
 * Permanently delete a lead (spec: pilot leads are kept until deleted). The admin must type the
 * venue name; the audit entry keeps only the id and status, not the deleted personal data.
 */
export async function deleteLead(_prev: ActionResult, formData: FormData): Promise<ActionResult> {
  const { admin } = await requireAdmin();
  const leadId = z.uuid().safeParse(formData.get('leadId'));
  if (!leadId.success) return actionError('That lead no longer exists.');
  const outcome = await getDb().$transaction(async (tx) => {
    const lead = await tx.pilotLead.findUnique({ where: { id: leadId.data }, select: { status: true, createdAt: true } });
    if (!lead) return 'missing' as const;
    await tx.pilotLead.delete({ where: { id: leadId.data } });
    await adminAudit(tx, admin.id, 'admin.lead.deleted', { leadId: leadId.data, status: lead.status, submittedAt: lead.createdAt });
    return 'ok' as const;
  });
  if (outcome === 'missing') return actionError('That lead was already deleted.');
  revalidatePath('/admin/leads', 'layout');
  // Navigate server-side: re-rendering the deleted lead's page would only show a 404.
  redirect('/admin/leads?deleted=1');
}
