"use server";

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

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

// =====================================================================
// /dashboard/kalender · Server Actions
// =====================================================================

const terminSchema = z.object({
  title: z.string().trim().min(2, "Titel muss mindestens 2 Zeichen lang sein"),
  description: z.string().trim().optional(),
  type: z.nativeEnum(TerminType),
  startDate: z.string().datetime(),
  endDate: z.string().datetime(),
  allDay: z.boolean().default(false),
  mitbringselListEnabled: z.boolean().default(false),
  requiresRsvp: z.boolean().default(false),
  rsvpDeadline: z.string().datetime().nullable().optional(),
  participantInfo: z.string().trim().max(1000).optional(),
});

function buildTerminData(data: z.infer<typeof terminSchema>) {
  const startDate = new Date(data.startDate);
  const endDate = new Date(data.endDate);
  const now = new Date();
  now.setSeconds(0, 0);

  if (startDate < now) {
    return { error: "Der Startzeitpunkt darf nicht in der Vergangenheit liegen." };
  }

  if (endDate < startDate) {
    return { error: "Das Enddatum darf nicht vor dem Startdatum liegen." };
  }

  return {
    data: {
      title: data.title,
      description: data.description || null,
      type: data.type,
      startDate,
      endDate,
      allDay: data.allDay,
      mitbringselListEnabled: data.mitbringselListEnabled,
      requiresRsvp: data.requiresRsvp,
      rsvpDeadline:
        data.requiresRsvp && data.rsvpDeadline
          ? new Date(data.rsvpDeadline)
          : null,
      participantInfo:
        data.requiresRsvp && data.participantInfo
          ? data.participantInfo
          : null,
    },
  };
}

export async function createTerminRequest(rawPayload: unknown) {
  const session = await requireKitaSession();
  
  const parsed = terminSchema.safeParse(rawPayload);
  if (!parsed.success) {
    return { error: "Ungültige Eingabedaten." };
  }
  
  const data = parsed.data;
  const terminData = buildTerminData(data);

  if ("error" in terminData) {
    return { error: terminData.error };
  }

  try {
    await prisma.termin.create({
      data: {
        kitaId: session.user.kitaId,
        createdById: session.user.id,
        title: terminData.data.title,
        description: terminData.data.description,
        type: terminData.data.type,
        startDate: terminData.data.startDate,
        endDate: terminData.data.endDate,
        allDay: terminData.data.allDay,
        status: TerminStatus.PENDING,
      },
    });

    revalidatePath("/dashboard/kalender");
    return { success: true };
  } catch (error) {
    console.error("Fehler beim Erstellen der Terminanfrage:", error);
    return { error: "Ein Fehler ist aufgetreten." };
  }
}

export async function createTerminAdmin(rawPayload: unknown) {
  const session = await requireRole([UserRole.ADMIN, UserRole.KOORDINATOR]);
  const kitaId = session.user.kitaId;
  if (!kitaId) {
    return { error: "Kein Mandant zugeordnet." };
  }
  
  const parsed = terminSchema.safeParse(rawPayload);
  if (!parsed.success) {
    return { error: "Ungültige Eingabedaten." };
  }
  
  const data = parsed.data;
  const terminData = buildTerminData(data);

  if ("error" in terminData) {
    return { error: terminData.error };
  }

  try {
    await prisma.termin.create({
      data: {
        kitaId,
        createdById: session.user.id,
        ...terminData.data,
        status: TerminStatus.CONFIRMED,
        approvedById: session.user.id,
        approvedAt: new Date(),
      },
    });

    revalidatePath("/dashboard/kalender");
    revalidatePath("/dashboard/admin/kalender");
    return { success: true };
  } catch (error) {
    console.error("Fehler beim Erstellen des Termins:", error);
    return { error: "Ein Fehler ist aufgetreten." };
  }
}

export async function updateTerminAdmin(terminId: string, rawPayload: unknown) {
  const session = await requireRole([UserRole.ADMIN, UserRole.KOORDINATOR]);
  const kitaId = session.user.kitaId;

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

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

  const terminData = buildTerminData(parsed.data);
  if ("error" in terminData) {
    return { error: terminData.error };
  }

  try {
    await prisma.termin.update({
      where: {
        id: terminId,
        kitaId,
      },
      data: terminData.data,
    });

    revalidatePath("/dashboard/kalender");
    revalidatePath("/dashboard/admin/kalender");
    revalidatePath("/dashboard");
    return { success: true };
  } catch (error) {
    console.error("Fehler beim Aktualisieren des Termins:", error);
    return { error: "Termin konnte nicht aktualisiert werden." };
  }
}

export async function approveTermin(terminId: string) {
  const session = await requireRole([UserRole.ADMIN, UserRole.KOORDINATOR]);
  const kitaId = session.user.kitaId;
  if (!kitaId) {
    return { error: "Kein Mandant zugeordnet." };
  }

  try {
    await prisma.termin.update({
      where: {
        id: terminId,
        kitaId,
      },
      data: {
        status: TerminStatus.CONFIRMED,
        approvedById: session.user.id,
        approvedAt: new Date(),
      },
    });

    revalidatePath("/dashboard/kalender");
    revalidatePath("/dashboard/admin/kalender");
    return { success: true };
  } catch (error) {
    console.error("Fehler beim Bestätigen des Termins:", error);
    return { error: "Ein Fehler ist aufgetreten." };
  }
}

export async function rejectTermin(terminId: string, reason?: string) {
  const session = await requireRole([UserRole.ADMIN, UserRole.KOORDINATOR]);
  const kitaId = session.user.kitaId;
  if (!kitaId) {
    return { error: "Kein Mandant zugeordnet." };
  }

  try {
    await prisma.termin.update({
      where: {
        id: terminId,
        kitaId,
      },
      data: {
        status: TerminStatus.REJECTED,
        rejectionReason: reason,
        approvedById: session.user.id,
        approvedAt: new Date(),
      },
    });

    revalidatePath("/dashboard/kalender");
    revalidatePath("/dashboard/admin/kalender");
    return { success: true };
  } catch (error) {
    console.error("Fehler beim Ablehnen des Termins:", error);
    return { error: "Ein Fehler ist aufgetreten." };
  }
}

export async function toggleMitbringselList(terminId: string, enabled: boolean) {
  const session = await requireRole([UserRole.ADMIN, UserRole.KOORDINATOR]);
  const kitaId = session.user.kitaId;
  if (!kitaId) {
    return { error: "Kein Mandant zugeordnet." };
  }

  try {
    await prisma.termin.update({
      where: {
        id: terminId,
        kitaId,
      },
      data: {
        mitbringselListEnabled: enabled,
      },
    });

    revalidatePath("/dashboard/kalender");
    revalidatePath("/dashboard/admin/kalender");
    return { success: true };
  } catch (error) {
    console.error("Fehler beim Umschalten der Mitbring-Liste:", error);
    return { error: "Ein Fehler ist aufgetreten." };
  }
}

const mitbringselSchema = z.object({
  terminId: z.string(),
  content: z.string().min(1, "Eintrag darf nicht leer sein"),
});

export async function addMitbringsel(rawPayload: unknown) {
  const session = await requireKitaSession();
  
  const parsed = mitbringselSchema.safeParse(rawPayload);
  if (!parsed.success) {
    return { error: "Ungültige Eingabedaten." };
  }
  
  const { terminId, content } = parsed.data;

  try {
    // Verify termin is active and list is enabled
    const termin = await prisma.termin.findUnique({
      where: { id: terminId, kitaId: session.user.kitaId },
    });

    if (!termin || termin.status !== TerminStatus.CONFIRMED || !termin.mitbringselListEnabled) {
      return { error: "Mitbring-Liste ist für diesen Termin nicht aktiv." };
    }

    await prisma.mitbringselItem.create({
      data: {
        kitaId: session.user.kitaId,
        terminId: terminId,
        userId: session.user.id,
        content: content,
      },
    });

    revalidatePath("/dashboard/kalender");
    return { success: true };
  } catch (error) {
    console.error("Fehler beim Hinzufügen des Eintrags:", error);
    return { error: "Ein Fehler ist aufgetreten." };
  }
}

export async function deleteMitbringsel(itemId: string) {
  const session = await requireKitaSession();

  try {
    const item = await prisma.mitbringselItem.findUnique({
      where: { id: itemId, kitaId: session.user.kitaId },
    });

    if (!item) {
      return { error: "Eintrag nicht gefunden." };
    }

    // Admins/Koords can delete any item. Users can only delete their own.
    if (
      session.user.role !== UserRole.ADMIN &&
      session.user.role !== UserRole.KOORDINATOR &&
      item.userId !== session.user.id
    ) {
      return { error: "Keine Berechtigung diesen Eintrag zu löschen." };
    }

    await prisma.mitbringselItem.delete({
      where: { id: itemId },
    });

    revalidatePath("/dashboard/kalender");
    return { success: true };
  } catch (error) {
    console.error("Fehler beim Löschen des Eintrags:", error);
    return { error: "Ein Fehler ist aufgetreten." };
  }
}
