"use server";

import { revalidatePath } from "next/cache";
import { prisma } from "@/lib/prisma";
import { requireSession } from "@/lib/auth/session";
import { createNotification } from "@/lib/notifications";
import { getAbsenceTypes } from "@/lib/settings";

export type AbsenceResult = { error?: string; ok?: boolean };

function parseDate(v: string): Date | null {
  const d = new Date(v);
  return Number.isNaN(d.getTime()) ? null : d;
}

export async function requestAbsenceAction(input: {
  type: string;
  startDate: string;
  endDate: string;
  reason?: string;
}): Promise<AbsenceResult> {
  const session = await requireSession();
  if (!session.user.permissions?.includes("absences.request")) return { error: "Keine Berechtigung." };

  const types = await getAbsenceTypes();
  const type = types.find((t) => t.key === input.type)?.key ?? types[0]?.key ?? "VACATION";
  const start = parseDate(input.startDate);
  const end = parseDate(input.endDate);
  if (!start || !end) return { error: "Bitte Start- und Enddatum angeben." };
  if (end < start) return { error: "Enddatum darf nicht vor dem Start liegen." };

  await prisma.absenceRequest.create({
    data: {
      userId: session.user.id,
      type,
      startDate: start,
      endDate: end,
      reason: input.reason?.trim().slice(0, 500) || null,
      status: "PENDING",
    },
  });

  // Zuständige Person benachrichtigen: eigene(r) Vorgesetzte(r), sonst alle Genehmigenden.
  const me = await prisma.user.findUnique({ where: { id: session.user.id }, select: { supervisorId: true } });
  const approverIds = me?.supervisorId
    ? [me.supervisorId]
    : (
        await prisma.user.findMany({
          where: {
            status: "ACTIVE",
            roles: { some: { role: { permissions: { some: { permission: { key: "absences.approve" } } } } } },
            id: { not: session.user.id },
          },
          select: { id: true },
        })
      ).map((a) => a.id);

  for (const id of approverIds) {
    await createNotification({
      userId: id,
      type: "ABSENCE",
      title: "Neuer Abwesenheitsantrag",
      body: `${session.user.name ?? "Ein Mitglied"} hat einen Antrag gestellt.`,
      link: "/admin/users",
    });
  }

  revalidatePath("/absences");
  revalidatePath("/admin/users");
  return { ok: true };
}

export async function cancelAbsenceAction(id: string): Promise<AbsenceResult> {
  const session = await requireSession();
  const absence = await prisma.absenceRequest.findUnique({ where: { id }, select: { userId: true, status: true } });
  if (!absence || absence.userId !== session.user.id) return { error: "Nicht gefunden." };
  if (absence.status === "REJECTED" || absence.status === "CANCELLED") return { error: "Bereits abgeschlossen." };
  await prisma.absenceRequest.update({ where: { id }, data: { status: "CANCELLED" } });
  revalidatePath("/absences");
  return { ok: true };
}

export async function decideAbsenceAction(id: string, approve: boolean): Promise<AbsenceResult> {
  const session = await requireSession();

  const absence = await prisma.absenceRequest.findUnique({
    where: { id },
    select: { userId: true, status: true, user: { select: { supervisorId: true } } },
  });
  if (!absence) return { error: "Nicht gefunden." };
  if (absence.status !== "PENDING") return { error: "Antrag ist nicht mehr offen." };

  // Erlaubt: zuständige(r) Vorgesetzte(r) ODER globales Genehmigungsrecht.
  const isSupervisor = absence.user.supervisorId === session.user.id;
  const canApprove = Boolean(session.user.permissions?.includes("absences.approve"));
  if (!isSupervisor && !canApprove) return { error: "Keine Berechtigung." };

  await prisma.absenceRequest.update({
    where: { id },
    data: {
      status: approve ? "APPROVED" : "REJECTED",
      approverId: session.user.id,
      decidedAt: new Date(),
    },
  });

  await createNotification({
    userId: absence.userId,
    type: "ABSENCE",
    title: approve ? "Abwesenheit genehmigt" : "Abwesenheit abgelehnt",
    body: approve ? "Dein Antrag wurde genehmigt." : "Dein Antrag wurde abgelehnt.",
    link: "/absences",
  });

  revalidatePath("/absences");
  revalidatePath("/admin/users");
  return { ok: true };
}
