import Link from "next/link";
import { addMonths, getYear, getMonth, format } from "date-fns";
import { de } from "date-fns/locale";
import { TerminType, UserRole } from "@prisma/client";
import { ChevronLeft, ChevronRight } from "lucide-react";

import { requireRole } from "@/lib/auth-utils";
import { prisma } from "@/lib/prisma";
import { getWorkingDaysOfMonth } from "@/lib/date-utils";
import { PlanView } from "./plan-view";
import { SettingsModal } from "./_components/settings-modal";

export const metadata = { title: "Plan-Generierung · Kita-Planer" };

export default async function PlanungsZentralePage({
  searchParams,
}: {
  searchParams: Promise<{ year?: string; month?: string }>;
}) {
  const session = await requireRole([UserRole.ADMIN, UserRole.KOORDINATOR]);
  const kitaId = session.user.kitaId!;

  const resolvedSearchParams = await searchParams;
  const now = new Date();
  const nextMonth = addMonths(now, 1);
  const targetYear = resolvedSearchParams.year ? parseInt(resolvedSearchParams.year, 10) : getYear(nextMonth);
  const targetMonth = resolvedSearchParams.month ? parseInt(resolvedSearchParams.month, 10) : (getMonth(nextMonth) + 1);

  const monthDate = new Date(targetYear, targetMonth - 1, 1);
  const monthName = format(monthDate, "MMMM", { locale: de });

  const workingDays = getWorkingDaysOfMonth(targetYear, targetMonth);
  const monthStart = new Date(targetYear, targetMonth - 1, 1);
  const monthEnd = new Date(targetYear, targetMonth, 1);

  const [plan, families, availabilities, closureCount, kita] = await Promise.all([
    prisma.notdienstPlan.findUnique({
      where: {
        kitaId_year_month: { kitaId, year: targetYear, month: targetMonth },
      },
      select: {
        id: true,
        status: true,
        assignments: {
          select: {
            id: true,
            childId: true,
            date: true,
          },
        },
      },
    }),
    prisma.family.findMany({
      where: {
        kitaId,
        children: { some: { active: true } },
      },
      select: {
        id: true,
        name: true,
        children: {
          where: { active: true },
          select: { id: true },
        },
      },
      orderBy: { name: "asc" },
    }),
    prisma.notdienstAvailability.findMany({
      where: {
        kitaId,
        date: {
          gte: monthStart,
          lt: monthEnd,
        },
      },
      select: {
        date: true,
        child: {
          select: {
            familyId: true,
          },
        },
      },
      orderBy: { date: "asc" },
    }),
    prisma.termin.count({
      where: {
        kitaId,
        type: TerminType.SCHLIESSTAG,
        startDate: {
          gte: monthStart,
          lt: monthEnd,
        },
      },
    }),
    prisma.kita.findUniqueOrThrow({
      where: { id: kitaId },
      select: {
        notdienstMinPerChildPerMonth: true,
        notdienstReminderDaysBefore: true,
      },
    }),
  ]);

  // Wir laden auch alle aktiven Kinder (inkl. Eltern-Namen) für das manuelle Dropdown.
  // Idealerweise gruppiert man das nach "Verfügbar an diesem Tag" und "Alle", 
  // aber für MVP reichen alle aktiven Kinder.
  const allChildrenRaw = await prisma.child.findMany({
    where: { kitaId, active: true },
    select: {
      id: true,
      firstName: true,
      lastName: true,
      family: {
        select: {
          name: true,
          users: {
            select: {
              firstName: true,
              lastName: true,
            },
          },
        },
      },
    },
    orderBy: { lastName: "asc" },
  });

  const allChildren = allChildrenRaw.map((c) => {
    const parentName =
      c.family.users
        .map((parent) => `${parent.firstName} ${parent.lastName}`)
        .join(", ") || c.family.name;
    return {
      id: c.id,
      name: `${c.firstName} ${c.lastName}`,
      parentName,
    };
  });

  const availabilityDatesByFamily = new Map<string, Set<string>>();
  availabilities.forEach((availability) => {
    const familyId = availability.child.familyId;
    const dates = availabilityDatesByFamily.get(familyId) ?? new Set<string>();
    dates.add(availability.date.toISOString());
    availabilityDatesByFamily.set(familyId, dates);
  });

  const familyStatuses = families.map((family) => {
    const dates = Array.from(availabilityDatesByFamily.get(family.id) ?? []);
    return {
      id: family.id,
      name: family.name,
      selectedDays: dates.map((date) => ({
        iso: date,
        label: new Intl.DateTimeFormat("de-DE", {
          weekday: "short",
          day: "2-digit",
          month: "2-digit",
        }).format(new Date(date)),
      })),
      childCount: family.children.length,
    };
  });

  const respondedFamilies = familyStatuses.filter(
    (family) => family.selectedDays.length > 0,
  ).length;
  const openFamilies = Math.max(familyStatuses.length - respondedFamilies, 0);
  const totalAvailabilitySlots = availabilities.length;
  const requiredDays = workingDays.length;
  const coverageFactor =
    requiredDays > 0 ? totalAvailabilitySlots / requiredDays : 0;

  // Wir mappen die Assignments auf die Werktage
  const daysWithAssignments = workingDays.map((day) => {
    const assignment = plan?.assignments.find(
      (a) => a.date.getTime() === day.getTime()
    );
    return {
      date: day.toISOString(),
      assignmentId: assignment?.id || null,
      childId: assignment?.childId || null,
    };
  });

  return (
    <div className="mx-auto max-w-[1280px] px-11 py-9 pb-16 max-[760px]:px-5">
      <header className="mb-7 flex items-end justify-between gap-8 max-[900px]:items-start max-[900px]:flex-col">
        <div>
          <p className="text-[11px] font-semibold uppercase text-[var(--accent-deep)] [letter-spacing:0.18em]">
            NOTDIENST · PLANUNG
          </p>
          <h1 className="mt-2 text-[36px] font-normal leading-tight tracking-[-0.025em] text-[var(--ink)]">
            Notdienst{" "}
            <em className="font-normal italic text-[var(--accent-deep)]">
              zuweisen
            </em>
          </h1>
          <p className="mt-2 max-w-2xl text-[15px] leading-6 text-[var(--ink-soft)]">
            Koordiniere und generiere den Notdienst-Plan.
          </p>
        </div>

        <div className="print:hidden flex shrink-0 items-center gap-2">
          <div className="inline-flex overflow-hidden rounded-full border border-[var(--hairline)] bg-[var(--surface)]">
            <Link
              href={`/dashboard/notdienst/plan?year=${getYear(addMonths(monthDate, -1))}&month=${getMonth(addMonths(monthDate, -1)) + 1}`}
              className="inline-flex h-9 w-9 items-center justify-center border-r border-[var(--hairline-soft)] text-[var(--ink-soft)] hover:bg-[var(--surface-2)] hover:text-[var(--ink)] transition"
            >
              <ChevronLeft className="h-4 w-4 [stroke-width:1.7]" />
            </Link>
            <div className="flex h-9 min-w-36 items-center justify-center px-4 text-[13px] font-semibold text-[var(--ink)]">
              {monthName} {targetYear}
            </div>
            <Link
              href={`/dashboard/notdienst/plan?year=${getYear(addMonths(monthDate, 1))}&month=${getMonth(addMonths(monthDate, 1)) + 1}`}
              className="inline-flex h-9 w-9 items-center justify-center border-l border-[var(--hairline-soft)] text-[var(--ink-soft)] hover:bg-[var(--surface-2)] hover:text-[var(--ink)] transition"
            >
              <ChevronRight className="h-4 w-4 [stroke-width:1.7]" />
            </Link>
          </div>
          <SettingsModal
            initialMinPerChild={kita.notdienstMinPerChildPerMonth}
            initialReminderDays={kita.notdienstReminderDaysBefore}
          />
        </div>
      </header>

      <PlanView
        planId={plan?.id}
        status={plan?.status}
        days={daysWithAssignments}
        allChildren={allChildren}
        familyStatuses={familyStatuses}
        requiredDays={requiredDays}
        respondedFamilies={respondedFamilies}
        openFamilies={openFamilies}
        totalFamilies={familyStatuses.length}
        totalAvailabilitySlots={totalAvailabilitySlots}
        coverageFactor={coverageFactor}
        closureCount={closureCount}
        monthName={monthName}
        year={targetYear}
        month={targetMonth}
      />
    </div>
  );
}
