"use server";

import { auth } from "@/auth";
import { db } from "@/lib/db";
import { hasPermission } from "@/lib/permissions";
import { CREWING_ENABLED } from "@/lib/feature-flags";
import { AttendanceStatus } from "@prisma/client";
import { z } from "zod";
import { revalidatePath } from "next/cache";

type ActionResult = { ok: true } | { error: string };

const markSchema = z.object({ date: z.string().min(1), status: z.nativeEnum(AttendanceStatus) });

// Bulk-save the dirty cells from the month calendar (Site staff). One upsert per
// (assignment, date); a single ATTENDANCE_RECORDED audit row per save.
export async function saveAttendance(assignmentId: string, marks: { date: string; status: AttendanceStatus }[]): Promise<ActionResult> {
  if (!CREWING_ENABLED) return { error: "Crewing is not enabled" };
  const session = await auth();
  if (!session?.user) return { error: "Unauthorized" };
  if (!hasPermission(session.user.role, "record_attendance")) return { error: "Unauthorized" };

  if (!assignmentId) return { error: "Crew member is required" };
  const parsed = z.array(markSchema).max(40).safeParse(marks);
  if (!parsed.success) return { error: "Invalid attendance data" };
  if (parsed.data.length === 0) return { ok: true };

  const assignment = await db.crewAssignment.findUnique({ where: { id: assignmentId }, select: { crewMemberId: true } });
  if (!assignment) return { error: "Crew assignment not found" };

  await db.$transaction(
    parsed.data.map((m) =>
      db.attendance.upsert({
        where: { assignmentId_date: { assignmentId, date: new Date(m.date) } },
        update: { status: m.status, recordedById: session.user.id },
        create: { assignmentId, date: new Date(m.date), status: m.status, recordedById: session.user.id },
      })
    )
  );
  await db.crewAction.create({
    data: { actionType: "ATTENDANCE_RECORDED", actorId: session.user.id, crewMemberId: assignment.crewMemberId, metadata: { count: parsed.data.length } },
  });

  revalidatePath("/crewing/attendance");
  return { ok: true };
}
