import Link from "next/link";
import type { ComponentType } from "react";
import { format } from "date-fns";
import { de } from "date-fns/locale";
import {
  CalendarCheck2,
  CalendarClock,
  ChevronRight,
  Clock3,
  ListTodo,
  Users,
  type LucideProps,
} from "lucide-react";
import { UserRole } from "@prisma/client";

import { requireKitaSession } from "@/lib/auth-utils";
import { getTargetMonthData } from "@/lib/date-utils";
import { prisma } from "@/lib/prisma";
import { Stat } from "@/components/ui/stat";
import { OnboardingDialog } from "@/components/OnboardingDialog";
import { AbsenceCard, UpcomingAbsencesCard } from "./absence-card";

export const metadata = { title: "Übersicht · Kita-Planer" };

export default async function DashboardPage() {
  const session = await requireKitaSession();
  const now = new Date();
  const today = new Date(now);
  today.setHours(0, 0, 0, 0);

  const targetData = getTargetMonthData();
  const targetMonthStart = new Date(
    Date.UTC(targetData.targetYear, targetData.targetMonth - 1, 1),
  );
  const targetMonthEnd = new Date(
    Date.UTC(targetData.targetYear, targetData.targetMonth, 1),
  );

  const kita = await prisma.kita.findUniqueOrThrow({
    where: { id: session.user.kitaId },
    select: {
      name: true,
      notdienstModuleEnabled: true,
      notdienstMinPerChildPerMonth: true,
      terminModuleEnabled: true,
      adressbuchModuleEnabled: true,
    },
  });

  const [
    familyCount,
    childCount,
    todayAbsenceCount,
    notdienstAvailabilityCount,
    onboardingUser,
    absenceChildren,
    upcomingAbsences,
  ] = await Promise.all([
    prisma.family.count({
      where: { kitaId: session.user.kitaId },
    }),
    prisma.child.count({
      where: { kitaId: session.user.kitaId, active: true },
    }),
    prisma.absence.count({
      where: {
        kitaId: session.user.kitaId,
        startDate: { lte: today },
        endDate: { gte: today },
      },
    }),
    prisma.notdienstAvailability.count({
      where: {
        kitaId: session.user.kitaId,
        date: {
          gte: targetMonthStart,
          lt: targetMonthEnd,
        },
      },
    }),
    prisma.user.findFirstOrThrow({
      where: {
        id: session.user.id,
        kitaId: session.user.kitaId,
      },
      select: {
        phone: true,
        street: true,
        postalCode: true,
        city: true,
        familyId: true,
        role: true,
        family: {
          select: {
            _count: {
              select: {
                children: true,
              },
            },
          },
        },
      },
    }),
    session.user.familyId
      ? prisma.child.findMany({
          where: {
            kitaId: session.user.kitaId,
            familyId: session.user.familyId,
            active: true,
          },
          select: {
            id: true,
            firstName: true,
            lastName: true,
          },
          orderBy: [{ lastName: "asc" }, { firstName: "asc" }],
        })
      : Promise.resolve([]),
    session.user.familyId
      ? prisma.absence.findMany({
          where: {
            kitaId: session.user.kitaId,
            endDate: { gte: today },
            child: {
              familyId: session.user.familyId,
            },
          },
          select: {
            id: true,
            reason: true,
            note: true,
            startDate: true,
            endDate: true,
            child: {
              select: {
                firstName: true,
                lastName: true,
              },
            },
          },
          orderBy: [{ startDate: "asc" }],
          take: 6,
        })
      : Promise.resolve([]),
  ]);

  const canReportAbsences = session.user.role !== UserRole.ERZIEHER;
  const requiredNotdienstDays = Math.max(
    childCount * kita.notdienstMinPerChildPerMonth,
    1,
  );
  const openNotdienstDays = Math.max(
    requiredNotdienstDays - notdienstAvailabilityCount,
    0,
  );
  const todayPresentCount = Math.max(childCount - todayAbsenceCount, 0);
  const firstName =
    session.user.name?.split(" ")[0] ??
    session.user.email?.split("@")[0] ??
    "zusammen";

  return (
    <div className="mx-auto max-w-[1280px] px-11 py-9 pb-16 max-[760px]:px-5">
      <OnboardingDialog
        user={{
          phone: onboardingUser.phone,
          street: onboardingUser.street,
          postalCode: onboardingUser.postalCode,
          city: onboardingUser.city,
          familyId: onboardingUser.familyId,
          role: onboardingUser.role,
        }}
        family={
          onboardingUser.family
            ? { childrenCount: onboardingUser.family._count.children }
            : null
        }
      />

      <header className="mb-9 flex items-start justify-between gap-8">
        <div>
          <p className="text-[11px] font-semibold uppercase text-[var(--accent-deep)] [letter-spacing:0.18em]">
            ÜBERSICHT · {kita.name}
          </p>
          <h1 className="mt-2 text-[36px] font-normal leading-tight tracking-[-0.025em] text-[var(--ink)]">
            Willkommen{" "}
            <em className="font-normal italic text-[var(--accent-deep)]">
              zurück
            </em>
            , {firstName}.
          </h1>
          <p className="mt-3 max-w-2xl text-[15px] leading-6 text-[var(--ink-soft)]">
            Heute, {format(now, "EEEE, d. MMMM yyyy", { locale: de })}. Hier
            siehst du auf einen Blick, was bei {kita.name} ansteht und kannst
            dein Kind schnell für Abwesenheiten melden.
          </p>
        </div>
        <div className="mt-9 inline-flex shrink-0 items-center gap-2 rounded-full border border-[var(--hairline)] bg-[var(--surface)] px-4 py-2 text-[13px] font-semibold text-[var(--ink-soft)]">
          <Clock3 className="h-3.5 w-3.5 [stroke-width:1.7]" />
          {format(now, "EEE, d. MMM yyyy", { locale: de })}
        </div>
      </header>

      <div className="grid grid-cols-[minmax(0,1fr)_360px] gap-5 max-[1100px]:grid-cols-1">
        <div className="min-w-0">
          {canReportAbsences ? (
            <AbsenceCard
              today={format(today, "yyyy-MM-dd")}
              childOptions={absenceChildren.map((child) => ({
                id: child.id,
                name: `${child.firstName} ${child.lastName}`,
              }))}
              absences={upcomingAbsences.map((absence) => ({
                id: absence.id,
                childName: `${absence.child.firstName} ${absence.child.lastName}`,
                reason: absence.reason,
                note: absence.note,
                startDate: format(absence.startDate, "yyyy-MM-dd"),
                endDate: format(absence.endDate, "yyyy-MM-dd"),
              }))}
            />
          ) : null}
        </div>

        <aside>
          <UpcomingAbsencesCard
            absences={upcomingAbsences.map((absence) => ({
              id: absence.id,
              childName: `${absence.child.firstName} ${absence.child.lastName}`,
              reason: absence.reason,
              note: absence.note,
              startDate: format(absence.startDate, "yyyy-MM-dd"),
              endDate: format(absence.endDate, "yyyy-MM-dd"),
            }))}
          />
        </aside>
      </div>

      <section className="mt-5 grid grid-cols-4 gap-3.5 max-[1100px]:grid-cols-2 max-[640px]:grid-cols-1">
        <Stat label="Familien" value={familyCount} hint="registrierte Familien" />
        <Stat label="Kinder" value={childCount} hint="in der Einrichtung" />
        <Stat
          label={`Notdienst ${targetData.monthName}`}
          value={notdienstAvailabilityCount}
          suffix={`/ ${requiredNotdienstDays}`}
          hint={`Tage abgedeckt · ${openNotdienstDays} offen`}
        />
        <Stat
          label="Heute anwesend"
          value={todayPresentCount}
          hint="Kinder in der Kita"
        />
      </section>

      <section className="mt-7">
        <h2 className="text-lg font-medium tracking-[-0.02em] text-[var(--ink)]">
          Schnellstart
        </h2>
        <p className="mt-1 text-[13.5px] text-[var(--ink-soft)]">
          Häufige Aktionen für Vorstand und Koordination.
        </p>
        <div className="mt-4 grid grid-cols-3 gap-3 max-[1100px]:grid-cols-1">
          <QuickCard
            href="/dashboard/families"
            icon={Users}
            title="Familien verwalten"
            sub="Familien anlegen, Kinder zuordnen, Kontakte pflegen."
          />
          {kita.terminModuleEnabled ? (
            <QuickCard
              href="/dashboard/kalender"
              icon={CalendarClock}
              title="Terminkalender"
              sub="Schließtage, Elternabende und Feste planen."
            />
          ) : null}
          {kita.notdienstModuleEnabled ? (
            <QuickCard
              href="/dashboard/notdienst/plan"
              icon={ListTodo}
              title="Notdienst-Planung"
              sub="Verfügbarkeiten überblicken und Dienste zuweisen."
            />
          ) : null}
          {kita.adressbuchModuleEnabled ? (
            <QuickCard
              href="/dashboard/adressbuch"
              icon={CalendarCheck2}
              title="Adressbuch"
              sub="Kontakte der Kita-Gemeinschaft schnell finden."
            />
          ) : null}
        </div>
      </section>
    </div>
  );
}

function QuickCard({
  href,
  icon: Icon,
  title,
  sub,
}: {
  href: string;
  icon: ComponentType<LucideProps>;
  title: string;
  sub: string;
}) {
  return (
    <Link
      href={href}
      className="group flex min-h-[86px] items-center gap-4 rounded-[14px] border border-[var(--hairline)] bg-[var(--surface)] p-4 transition hover:border-[var(--accent-mid)] focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--focus-ring)]"
    >
      <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-[var(--accent-soft)] text-[var(--accent-deep)]">
        <Icon className="h-4.5 w-4.5 [stroke-width:1.7]" />
      </div>
      <div className="min-w-0 flex-1">
        <p className="truncate text-sm font-semibold text-[var(--ink)]">
          {title}
        </p>
        <p className="mt-1 line-clamp-2 text-[13px] leading-5 text-[var(--ink-soft)]">
          {sub}
        </p>
      </div>
      <ChevronRight className="h-4 w-4 shrink-0 text-[var(--ink-faint)] transition group-hover:translate-x-1 group-hover:text-[var(--accent-deep)]" />
    </Link>
  );
}
