import "server-only";
import { prisma } from "@/lib/prisma";
import { getAbsenceTypes } from "@/lib/settings";
import type { AbsenceStatus } from "@prisma/client";

export type AbsenceDTO = {
  id: string;
  userId: string;
  userName: string;
  type: string;
  status: AbsenceStatus;
  startDate: string;
  endDate: string;
  reason: string | null;
  decidedAt: string | null;
};

function mapAbsence(a: {
  id: string;
  userId: string;
  user: { name: string; displayName: string | null };
  type: string;
  status: AbsenceStatus;
  startDate: Date;
  endDate: Date;
  reason: string | null;
  decidedAt: Date | null;
}): AbsenceDTO {
  return {
    id: a.id,
    userId: a.userId,
    userName: a.user.displayName ?? a.user.name,
    type: a.type,
    status: a.status,
    startDate: a.startDate.toISOString(),
    endDate: a.endDate.toISOString(),
    reason: a.reason,
    decidedAt: a.decidedAt ? a.decidedAt.toISOString() : null,
  };
}

const sel = {
  id: true,
  userId: true,
  user: { select: { name: true, displayName: true } },
  type: true,
  status: true,
  startDate: true,
  endDate: true,
  reason: true,
  decidedAt: true,
} as const;

export async function getMyAbsences(userId: string): Promise<AbsenceDTO[]> {
  const rows = await prisma.absenceRequest.findMany({
    where: { userId },
    orderBy: { startDate: "desc" },
    select: sel,
  });
  return rows.map(mapAbsence);
}

/**
 * Offene Anträge zur Genehmigung. `supervisorId` = nur direkte Unterstellte,
 * sonst (mit globalem Recht) alle offenen Anträge.
 */
export async function getPendingAbsences(supervisorId?: string): Promise<AbsenceDTO[]> {
  const rows = await prisma.absenceRequest.findMany({
    where: {
      status: "PENDING",
      ...(supervisorId ? { user: { supervisorId } } : {}),
    },
    orderBy: { startDate: "asc" },
    select: sel,
  });
  return rows.map(mapAbsence);
}

/** Anzahl genutzter Urlaubstage im laufenden Jahr (genehmigt, urlaubszählende Arten). */
export async function getVacationUsed(userId: string): Promise<number> {
  const year = new Date().getFullYear();
  const types = await getAbsenceTypes();
  const vacationKeys = types.filter((t) => t.countsVacation).map((t) => t.key);
  if (vacationKeys.length === 0) return 0;

  const rows = await prisma.absenceRequest.findMany({
    where: {
      userId,
      type: { in: vacationKeys },
      status: "APPROVED",
      startDate: { gte: new Date(year, 0, 1) },
      endDate: { lte: new Date(year, 11, 31, 23, 59, 59) },
    },
    select: { startDate: true, endDate: true },
  });
  let days = 0;
  for (const r of rows) {
    days += Math.round((r.endDate.getTime() - r.startDate.getTime()) / 86400000) + 1;
  }
  return days;
}
