"use server";

import { revalidatePath } from "next/cache";
import { UserRole } from "@prisma/client";
import { z } from "zod";

import { requireRole } from "@/lib/auth-utils";
import { prisma } from "@/lib/prisma";
import { getTargetMonthData } from "@/lib/date-utils";

// =====================================================================
// /dashboard/notdienst · Server Actions
// ---------------------------------------------------------------------
// Speichert die gebuchten Termine der Eltern im Zielmonat.
// Die Termine werden Round-Robin auf die Kinder aufgeteilt.
// =====================================================================

const payloadSchema = z.object({
  childrenIds: z.array(z.string()).min(1),
  dates: z.array(z.string().datetime()), // ISO strings
});

export async function saveNotdienstAvailabilities(payloadRaw: {
  childrenIds: string[];
  dates: string[];
}) {
  const session = await requireRole([
    UserRole.ELTERN,
    UserRole.ADMIN,
    UserRole.KOORDINATOR,
  ]);

  const parsed = payloadSchema.safeParse(payloadRaw);
  if (!parsed.success) {
    return { error: "Ungültige Eingabedaten." };
  }

  const { childrenIds, dates } = parsed.data;

  // ── 1. Sperrfrist prüfen ───────────────────────────────────────────
  const { targetYear, targetMonth, isLocked } = getTargetMonthData();
  if (isLocked) {
    return { error: "Die Planung für diesen Monat ist bereits abgeschlossen." };
  }

  const kitaId = session.user.kitaId;
  if (!kitaId) {
    return { error: "Kein Mandant zugeordnet." };
  }
  if (!session.user.familyId) {
    return { error: "Dein Account ist noch keinem Haushalt zugeordnet." };
  }

  // ── 2. Validierung (Soll-Tage) ─────────────────────────────────────
  const kita = await prisma.kita.findUniqueOrThrow({
    where: { id: kitaId },
    select: { notdienstMinPerChildPerMonth: true },
  });

  const requiredTotal = childrenIds.length * kita.notdienstMinPerChildPerMonth;
  if (dates.length < requiredTotal) {
    return {
      error: `Bitte wähle mindestens ${requiredTotal} Tage aus.`,
    };
  }

  // Sicherstellen, dass alle Kinder zum Haushalt des angemeldeten Users gehören.
  const validChildren = await prisma.child.findMany({
    where: {
      id: { in: childrenIds },
      kitaId,
      familyId: session.user.familyId,
    },
    select: { id: true },
  });

  if (validChildren.length !== childrenIds.length) {
    return { error: "Ungültige Kinder-Zuordnung erkannt." };
  }

  // Termine in Date-Objekte wandeln und sortieren
  const parsedDates = dates
    .map((d) => new Date(d))
    .sort((a, b) => a.getTime() - b.getTime());

  // Round-Robin Zuweisung
  const inserts: {
    kitaId: string;
    childId: string;
    userId: string;
    date: Date;
  }[] = [];

  for (let i = 0; i < parsedDates.length; i++) {
    const childId = validChildren[i % validChildren.length].id;
    inserts.push({
      kitaId,
      childId,
      userId: session.user.id,
      date: parsedDates[i],
    });
  }

  // ── 3. Datenbank-Transaktion ───────────────────────────────────────
  try {
    await prisma.$transaction(async (tx) => {
      // a) Alle bestehenden Haushaltseinträge im Zielmonat für diese Kinder löschen
      await tx.notdienstAvailability.deleteMany({
        where: {
          kitaId,
          childId: { in: childrenIds },
          date: {
            gte: new Date(targetYear, targetMonth - 1, 1),
            lt: new Date(targetYear, targetMonth, 1),
          },
        },
      });

      // b) Neue Einträge setzen
      if (inserts.length > 0) {
        await tx.notdienstAvailability.createMany({
          data: inserts,
          skipDuplicates: true,
        });
      }
    });

    revalidatePath("/dashboard/notdienst");
    return { success: true };
  } catch (error) {
    console.error("Fehler beim Speichern der Notdienste:", error);
    return { error: "Ein Fehler ist aufgetreten beim Speichern der Termine." };
  }
}
