import "server-only";
import { prisma } from "@/lib/prisma";
import { computePresence, type Presence, type PresenceInfo } from "@/lib/presence";

/** Aktualisiert den „zuletzt gesehen"-Zeitstempel (Heartbeat). */
export async function touchPresence(userId: string): Promise<void> {
  await prisma.user.update({ where: { id: userId }, data: { lastSeenAt: new Date() } });
}

/** Präsenzstatus für mehrere Nutzer (inkl. Abwesenheits-/Urlaubsprüfung). */
export async function getPresenceMap(userIds: string[]): Promise<Record<string, Presence>> {
  const ids = [...new Set(userIds)].filter(Boolean);
  if (ids.length === 0) return {};
  const now = new Date();

  const [users, leaves] = await Promise.all([
    prisma.user.findMany({ where: { id: { in: ids } }, select: { id: true, lastSeenAt: true } }),
    prisma.absenceRequest.findMany({
      where: {
        userId: { in: ids },
        status: "APPROVED",
        startDate: { lte: now },
        endDate: { gte: now },
      },
      select: { userId: true },
    }),
  ]);

  const onLeave = new Set(leaves.map((l) => l.userId));
  const map: Record<string, Presence> = {};
  for (const u of users) map[u.id] = computePresence(u.lastSeenAt, onLeave.has(u.id));
  return map;
}

export async function getPresence(userId: string): Promise<Presence> {
  return (await getPresenceMap([userId]))[userId] ?? "offline";
}

/** Wie getPresenceMap, aber inkl. „zuletzt gesehen" (für Live-Anzeige/Label). */
export async function getPresenceInfoMap(userIds: string[]): Promise<Record<string, PresenceInfo>> {
  const ids = [...new Set(userIds)].filter(Boolean);
  if (ids.length === 0) return {};
  const now = new Date();

  const [users, leaves] = await Promise.all([
    prisma.user.findMany({ where: { id: { in: ids } }, select: { id: true, lastSeenAt: true } }),
    prisma.absenceRequest.findMany({
      where: { userId: { in: ids }, status: "APPROVED", startDate: { lte: now }, endDate: { gte: now } },
      select: { userId: true },
    }),
  ]);
  const onLeave = new Set(leaves.map((l) => l.userId));
  const map: Record<string, PresenceInfo> = {};
  for (const u of users) {
    map[u.id] = {
      status: computePresence(u.lastSeenAt, onLeave.has(u.id)),
      lastSeen: u.lastSeenAt ? u.lastSeenAt.toISOString() : null,
    };
  }
  return map;
}
