"use server";

import { revalidatePath } from "next/cache";
import { initDb } from "@/lib/db";
import { requireClientWorkspace } from "@/lib/auth/require-auth";
import { z } from "zod";
import type { ActionResult } from "@/lib/actions/auth";

const flagSchema = z.object({
  electionId: z.string().uuid(),
  voterRollId: z.string().uuid().optional().nullable(),
  eventType: z.enum([
    "duplicate_attempt",
    "invalid_authorization_block",
    "device_reuse_flag",
    "ai_anomaly_flag",
  ]),
  ipHash: z.string().max(64).optional().nullable(),
  deviceFingerprintHash: z.string().max(64).optional().nullable(),
  detail: z.record(z.string(), z.unknown()).optional().nullable(),
});

const reviewSchema = z.object({
  eventId: z.string().uuid(),
  reviewStatus: z.enum(["open", "dismissed", "confirmed_fraud"]),
});

export async function flagSecurityEvent(
  input: unknown
): Promise<ActionResult<{ eventId: string }>> {
  const { userId, workspaceId } = await requireClientWorkspace();
  const parsed = flagSchema.safeParse(input);
  if (!parsed.success) {
    return { success: false, error: parsed.error.issues[0]?.message ?? "Invalid input" };
  }

  const { Election, ElectionSecurityEvent, AuditLog } = initDb();
  const election = await Election.findOne({
    where: { id: parsed.data.electionId, workspaceId },
  });
  if (!election) return { success: false, error: "Election not found" };

  const event = await ElectionSecurityEvent.create({
    electionId: election.id,
    voterRollId: parsed.data.voterRollId ?? null,
    eventType: parsed.data.eventType,
    ipHash: parsed.data.ipHash ?? null,
    deviceFingerprintHash: parsed.data.deviceFingerprintHash ?? null,
    detail: parsed.data.detail ?? null,
    reviewStatus: "open",
  });

  await AuditLog.create({
    actorUserId: userId,
    workspaceId,
    action: "election_security.flagged",
    metadata: { eventId: event.id, eventType: event.eventType },
  });

  revalidatePath(`/app/elections/${election.id}`);
  return { success: true, data: { eventId: event.id } };
}

export async function reviewSecurityEvent(
  input: unknown
): Promise<ActionResult> {
  const { userId, workspaceId } = await requireClientWorkspace();
  const parsed = reviewSchema.safeParse(input);
  if (!parsed.success) {
    return { success: false, error: parsed.error.issues[0]?.message ?? "Invalid input" };
  }

  const { Election, ElectionSecurityEvent, AuditLog } = initDb();
  const event = await ElectionSecurityEvent.findByPk(parsed.data.eventId);
  if (!event) return { success: false, error: "Security event not found" };

  const election = await Election.findOne({
    where: { id: event.electionId, workspaceId },
  });
  if (!election) return { success: false, error: "Election not found" };

  await event.update({
    reviewStatus: parsed.data.reviewStatus,
    reviewedByUserId: userId,
  });

  await AuditLog.create({
    actorUserId: userId,
    workspaceId,
    action: "election_security.reviewed",
    metadata: {
      eventId: event.id,
      reviewStatus: parsed.data.reviewStatus,
    },
  });

  revalidatePath(`/app/elections/${election.id}`);
  return { success: true };
}
