"use server";

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

import { requireKitaSession, requireRole } from "@/lib/auth-utils";
import { prisma } from "@/lib/prisma";

const submitRsvpSchema = z.object({
  eventId: z.string().min(1),
  childId: z.string().min(1),
  status: z.nativeEnum(EventParticipationStatus),
});

export type EventParticipantDto = {
  childId: string;
  childName: string;
  familyName: string;
  status: EventParticipationStatus | null;
};

export async function submitEventRsvp(rawPayload: unknown) {
  const session = await requireKitaSession();
  const parsed = submitRsvpSchema.safeParse(rawPayload);

  if (!parsed.success) {
    return { error: "Ungültige Eingabedaten." };
  }

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

  const { eventId, childId, status } = parsed.data;

  const event = await prisma.termin.findFirst({
    where: {
      id: eventId,
      kitaId: session.user.kitaId,
    },
    select: {
      id: true,
      status: true,
      requiresRsvp: true,
      rsvpDeadline: true,
      startDate: true,
    },
  });

  if (!event || !event.requiresRsvp || event.status !== TerminStatus.CONFIRMED) {
    return { error: "Für diesen Termin ist keine Rückmeldung aktiv." };
  }

  const deadline = event.rsvpDeadline ?? event.startDate;
  if (deadline < new Date()) {
    return { error: "Die Rückmeldefrist ist bereits abgelaufen." };
  }

  const child = await prisma.child.findFirst({
    where: {
      id: childId,
      kitaId: session.user.kitaId,
      familyId: session.user.familyId,
      active: true,
    },
    select: { id: true },
  });

  if (!child) {
    return { error: "Dieses Kind gehört nicht zu deinem Haushalt." };
  }

  await prisma.eventParticipation.upsert({
    where: {
      eventId_childId: {
        eventId,
        childId,
      },
    },
    create: {
      kitaId: session.user.kitaId,
      eventId,
      childId,
      status,
    },
    update: {
      status,
    },
  });

  revalidatePath("/dashboard");
  revalidatePath("/dashboard/kalender");
  revalidatePath("/dashboard/admin/kalender");
  return { success: true };
}

export async function getEventParticipants(
  eventId: string,
): Promise<{ participants?: EventParticipantDto[]; error?: string }> {
  const session = await requireRole([UserRole.ADMIN, UserRole.KOORDINATOR]);
  const kitaId = session.user.kitaId;

  if (!kitaId) {
    return { error: "Kein Mandant zugeordnet." };
  }

  const event = await prisma.termin.findFirst({
    where: { id: eventId, kitaId },
    select: { id: true },
  });

  if (!event) {
    return { error: "Termin wurde nicht gefunden." };
  }

  const children = await prisma.child.findMany({
    where: {
      kitaId,
      active: true,
    },
    select: {
      id: true,
      firstName: true,
      lastName: true,
      family: {
        select: {
          name: true,
        },
      },
      eventParticipations: {
        where: { eventId },
        select: { status: true },
        take: 1,
      },
    },
    orderBy: [
      { family: { name: "asc" } },
      { lastName: "asc" },
      { firstName: "asc" },
    ],
  });

  return {
    participants: children.map((child) => ({
      childId: child.id,
      childName: `${child.firstName} ${child.lastName}`,
      familyName: child.family.name,
      status: child.eventParticipations[0]?.status ?? null,
    })),
  };
}
