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

// ──────────────────────────────────────────────────────────────────────────
// „Mein Tag" — persönliche Tagesübersicht fürs Dashboard: heutige Meetings,
// fällige Aufgaben, laufende Zeiterfassung und eigene Abwesenheit.
// ──────────────────────────────────────────────────────────────────────────

export type DayItemKind = "time" | "absence" | "meeting" | "task";

export type DayItem = {
  id: string;
  kind: DayItemKind;
  icon: string;
  accent: string;
  /** Uhrzeit bzw. Kurzlabel links in der Zeile. */
  time: string;
  title: string;
  subtitle: string | null;
  href: string;
  /** Hervorhebung für Überfälliges. */
  urgent: boolean;
};

export function startOfDay(d = new Date()): Date {
  return new Date(d.getFullYear(), d.getMonth(), d.getDate());
}
export function endOfDay(d = new Date()): Date {
  return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999);
}

const hhmm = (d: Date) =>
  d.toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" });

const PRIORITY_LABEL: Record<string, string> = {
  LOW: "Niedrig",
  MEDIUM: "Mittel",
  HIGH: "Hoch",
  URGENT: "Dringend",
};

/** Tagesübersicht eines Nutzers — bereits sortiert und anzeigefertig. */
export async function getMyDay(userId: string): Promise<DayItem[]> {
  const now = new Date();
  const start = startOfDay(now);
  const end = endOfDay(now);

  const [meetings, tasks, absence, running, absenceTypes] = await Promise.all([
    prisma.meeting.findMany({
      where: {
        startAt: { gte: start, lte: end },
        OR: [{ createdById: userId }, { participants: { some: { userId } } }],
      },
      orderBy: { startAt: "asc" },
      select: { id: true, title: true, startAt: true, endAt: true, location: true },
    }),
    prisma.task.findMany({
      where: {
        assignees: { some: { userId } },
        archivedAt: null,
        deadline: { not: null, lte: end },
      },
      orderBy: { deadline: "asc" },
      take: 6,
      select: {
        id: true,
        title: true,
        deadline: true,
        priority: true,
        column: { select: { name: true } },
      },
    }),
    prisma.absenceRequest.findFirst({
      where: {
        userId,
        status: "APPROVED",
        startDate: { lte: end },
        endDate: { gte: start },
      },
      select: { id: true, type: true, endDate: true },
    }),
    prisma.timeEntry.findFirst({
      where: { userId, status: "RUNNING" },
      orderBy: { startedAt: "desc" },
      select: { id: true, startedAt: true, project: { select: { name: true } } },
    }),
    getAbsenceTypes(),
  ]);

  const items: DayItem[] = [];

  if (running) {
    const minutes = Math.max(0, Math.floor((now.getTime() - running.startedAt.getTime()) / 60000));
    items.push({
      id: `time-${running.id}`,
      kind: "time",
      icon: "time",
      accent: "#7ee787",
      time: hhmm(running.startedAt),
      title: "Zeiterfassung läuft",
      subtitle: `${Math.floor(minutes / 60)} Std ${minutes % 60} Min${
        running.project ? ` · ${running.project.name}` : ""
      }`,
      href: "/time",
      urgent: false,
    });
  }

  if (absence) {
    const def = absenceTypes.find((t) => t.key === absence.type);
    items.push({
      id: `absence-${absence.id}`,
      kind: "absence",
      icon: "absences",
      accent: def?.color ?? "#9ed7ff",
      time: "heute",
      title: def?.label ?? "Abwesend",
      subtitle: `Genehmigt bis ${absence.endDate.toLocaleDateString("de-DE", {
        day: "2-digit",
        month: "2-digit",
      })}`,
      href: "/absences",
      urgent: false,
    });
  }

  for (const m of meetings) {
    items.push({
      id: `meeting-${m.id}`,
      kind: "meeting",
      icon: "meetings",
      accent: "var(--pink)",
      time: hhmm(m.startAt),
      title: m.title,
      subtitle: [`bis ${hhmm(m.endAt)}`, m.location].filter(Boolean).join(" · "),
      href: "/calendar",
      urgent: m.startAt > now && m.startAt.getTime() - now.getTime() < 60 * 60 * 1000,
    });
  }

  for (const t of tasks) {
    const deadline = t.deadline as Date;
    const overdue = deadline < start;
    items.push({
      id: `task-${t.id}`,
      kind: "task",
      icon: "kanban",
      accent: overdue ? "var(--pink)" : "var(--violet)",
      time: overdue ? "überfällig" : "fällig",
      title: t.title,
      subtitle: [
        overdue
          ? `seit ${deadline.toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit" })}`
          : "heute",
        t.column?.name,
        PRIORITY_LABEL[t.priority],
      ]
        .filter(Boolean)
        .join(" · "),
      href: "/kanban",
      urgent: overdue,
    });
  }

  return items;
}
