import Link from "next/link";
import { addDays, differenceInCalendarDays, format, isWeekend } from "date-fns";
import { de } from "date-fns/locale";
import {
  ArrowLeft,
  ArrowRight,
  CalendarCheck2,
  CalendarDays,
  ChevronDown,
  ChevronRight,
  Stethoscope,
} from "lucide-react";
import { AbsenceReason, TerminStatus, TerminType, UserRole } from "@prisma/client";

import { getDailyAbsences } from "@/actions/absences";
import { requireRole } from "@/lib/auth-utils";
import { prisma } from "@/lib/prisma";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import {
  AbsenceTable,
  type AbsenceTableItem,
} from "./absence-table";
import { reasonColor, reasonLabel } from "@/lib/absence-utils";

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

export default async function AdminAbwesenheitenPage({
  searchParams,
}: {
  searchParams: Promise<{ date?: string }>;
}) {
  const session = await requireRole([
    UserRole.ADMIN,
    UserRole.KOORDINATOR,
    UserRole.ERZIEHER,
  ]);
  const resolvedSearchParams = await searchParams;
  const kitaId = session.user.kitaId!;
  const today = startOfLocalDay(new Date());
  const selectedDate = parseDateParam(resolvedSearchParams.date, today);
  const dateKey = format(selectedDate, "yyyy-MM-dd");
  const result = await getDailyAbsences({ date: dateKey });
  const absences = result.absences ?? [];
  const childCount = await prisma.child.count({
    where: { kitaId, active: true },
  });
  const upcomingAbsenceCount = await prisma.absence.count({
    where: {
      kitaId,
      startDate: { gt: selectedDate },
    },
  });
  const closure = await prisma.termin.findFirst({
    where: {
      kitaId,
      status: TerminStatus.CONFIRMED,
      type: { in: [TerminType.SCHLIESSTAG, TerminType.TEAMTAG] },
      startDate: { lte: selectedDate },
      endDate: { gte: selectedDate },
    },
    select: { title: true, type: true },
    orderBy: { startDate: "asc" },
  });
  const isToday = dateKey === format(today, "yyyy-MM-dd");
  const isTooFarFuture = differenceInCalendarDays(selectedDate, today) > 30;
  const isClosedDay = isWeekend(selectedDate) || !!closure;
  const tableItems: AbsenceTableItem[] = absences.map((absence) => ({
    id: absence.id,
    childName: absence.childName,
    familyName: absence.familyName,
    reason: absence.reason,
    note: absence.note,
    startDate: absence.startDate,
    endDate: absence.endDate,
  }));
  const countsByReason = countByReason(tableItems);

  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-[1100px]:flex-col max-[1100px]:items-start">
        <div>
          <p className="text-[11px] font-semibold uppercase text-[var(--accent-deep)] [letter-spacing:0.18em]">
            TAGESÜBERSICHT
          </p>
          <h1 className="mt-2 text-[36px] font-normal leading-tight tracking-[-0.025em] text-[var(--ink)]">
            Heute fehlen{" "}
            <em className="font-normal italic text-[var(--accent-deep)]">
              {absences.length} Kinder
            </em>
          </h1>
          <p className="mt-2 text-[15px] leading-6 text-[var(--ink-soft)]">
            {format(selectedDate, "EEEE, d. MMMM yyyy", { locale: de })}
          </p>
        </div>

        <div className="flex flex-wrap items-center justify-end gap-3">
          <span className="inline-flex h-9 items-center gap-2 rounded-full border border-[var(--hairline)] bg-[var(--surface)] px-3 text-[13px] font-semibold text-[var(--ink-soft)]">
            <Stethoscope className="h-4 w-4 text-[var(--accent-deep)] [stroke-width:1.7]" />
            {childCount - absences.length} anwesend
          </span>
          <div className="inline-flex overflow-hidden rounded-full border border-[var(--hairline)] bg-[var(--surface)]">
            <SegmentLink href={hrefForDate(addDays(selectedDate, -1))}>
              <ArrowLeft className="h-3.5 w-3.5" />
              Zurück
            </SegmentLink>
            <SegmentLink href={hrefForDate(today)} active={isToday}>
              Heute
            </SegmentLink>
            <SegmentLink href={hrefForDate(addDays(selectedDate, 1))}>
              Vor
              <ArrowRight className="h-3.5 w-3.5" />
            </SegmentLink>
          </div>
          <form className="flex items-center gap-2">
            <Input
              type="date"
              name="date"
              defaultValue={dateKey}
              className="w-[140px]"
            />
            <Button type="submit">Anzeigen</Button>
          </form>
        </div>
      </header>

      <div className="mt-5 flex flex-wrap items-center justify-between gap-3">
        <div className="flex flex-wrap gap-2">
          <FilterChip label="Alle Gruppen" />
          <FilterChip label="Alle Gründe" />
        </div>
        {tableItems.length > 0 ? (
          <div className="flex flex-wrap items-center gap-4 text-xs text-[var(--ink-soft)]">
            <ReasonInlineStat
              reason={AbsenceReason.ILLNESS}
              count={countsByReason[AbsenceReason.ILLNESS] ?? 0}
            />
            <ReasonInlineStat
              reason={AbsenceReason.OTHER}
              count={countsByReason[AbsenceReason.OTHER] ?? 0}
            />
            <ReasonInlineStat
              reason={AbsenceReason.VACATION}
              count={countsByReason[AbsenceReason.VACATION] ?? 0}
            />
            <span>
              letzte Aktualisierung {format(new Date(), "HH:mm", { locale: de })}
            </span>
          </div>
        ) : null}
      </div>

      <div className="mt-4">
        {result.error ? (
          <Card className="border-[var(--danger)] bg-[var(--danger-soft)]">
            <CardContent className="pt-[22px] text-sm text-[var(--danger)]">
              {result.error}
            </CardContent>
          </Card>
        ) : tableItems.length > 0 ? (
          <Card>
            <CardHeader className="pb-4">
              <div className="flex flex-wrap items-center justify-between gap-3">
                <CardTitle>
                  {tableItems.length} von {childCount} Kindern abwesend ·{" "}
                  {upcomingAbsenceCount} anstehend
                </CardTitle>
                <Badge variant="secondary">{dateKey}</Badge>
              </div>
            </CardHeader>
            <CardContent>
              <AbsenceTable absences={tableItems} />
            </CardContent>
          </Card>
        ) : isTooFarFuture ? (
          <EmptyState
            tone="accent"
            title="Noch nicht im Vorschauzeitraum"
            description="Abwesenheiten werden erst 30 Tage im Voraus angezeigt."
          />
        ) : isClosedDay ? (
          <EmptyState
            tone="accent"
            title={`Kita geschlossen am ${format(selectedDate, "d. MMMM", {
              locale: de,
            })}`}
            description={
              closure
                ? closure.title
                : "Wochenende · für diesen Tag werden keine Anwesenheiten erwartet."
            }
          />
        ) : (
          <EmptyState
            tone="good"
            title="Keine Abwesenheiten"
            description="Für diesen Tag sind aktuell keine Kinder abgemeldet."
          />
        )}
      </div>
    </div>
  );
}

function SegmentLink({
  href,
  active,
  children,
}: {
  href: string;
  active?: boolean;
  children: React.ReactNode;
}) {
  return (
    <Link
      href={href}
      className={[
        "inline-flex h-10 items-center gap-2 border-r border-[var(--hairline)] px-4 text-[13px] font-semibold text-[var(--ink-soft)] transition last:border-r-0 hover:bg-[var(--surface-2)] hover:text-[var(--ink)] focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--focus-ring)]",
        active ? "bg-[var(--accent-soft)] text-[var(--accent-deep)]" : "",
      ].join(" ")}
    >
      {children}
    </Link>
  );
}

function FilterChip({ label }: { label: string }) {
  return (
    <button
      type="button"
      className="inline-flex h-9 items-center gap-2 rounded-full border border-[var(--hairline)] bg-transparent px-4 text-[13px] font-semibold text-[var(--ink-soft)] transition hover:bg-[var(--accent-soft)] hover:text-[var(--accent-deep)] focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--focus-ring)]"
    >
      {label}
      <ChevronDown className="h-3.5 w-3.5" />
    </button>
  );
}

function ReasonInlineStat({
  reason,
  count,
}: {
  reason: AbsenceReason;
  count: number;
}) {
  return (
    <span className="inline-flex items-center gap-1.5">
      <span
        className="h-2 w-2 rounded-full"
        style={{ backgroundColor: reasonColor(reason) }}
      />
      {reasonLabel(reason)} {count}
    </span>
  );
}

function EmptyState({
  tone,
  title,
  description,
}: {
  tone: "good" | "accent";
  title: string;
  description: string;
}) {
  const isGood = tone === "good";

  return (
    <Card>
      <CardContent className="flex max-h-[280px] min-h-[260px] flex-col items-center justify-center px-8 py-12 text-center">
        <div
          className={[
            "flex h-12 w-12 items-center justify-center rounded-2xl",
            isGood
              ? "bg-[var(--good-soft)] text-[var(--good)]"
              : "bg-[var(--accent-soft)] text-[var(--accent-deep)]",
          ].join(" ")}
        >
          {isGood ? (
            <CalendarCheck2 className="h-6 w-6 [stroke-width:1.7]" />
          ) : (
            <CalendarDays className="h-6 w-6 [stroke-width:1.7]" />
          )}
        </div>
        <h2 className="mt-5 text-lg font-medium tracking-[-0.02em] text-[var(--ink)]">
          {title}
        </h2>
        <p className="mt-2 max-w-md text-sm text-[var(--ink-soft)]">
          {description}
        </p>
        <Link
          href="/dashboard/admin/abwesenheiten"
          className="mt-5 inline-flex items-center gap-1 text-sm font-semibold text-[var(--accent-deep)] transition hover:gap-2 focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--focus-ring)]"
        >
          Wochenübersicht öffnen
          <ChevronRight className="h-3.5 w-3.5" />
        </Link>
      </CardContent>
    </Card>
  );
}

function parseDateParam(value: string | undefined, fallback: Date) {
  if (!value) return fallback;
  const parsed = new Date(`${value}T00:00:00`);
  return Number.isNaN(parsed.getTime()) ? fallback : parsed;
}

function hrefForDate(date: Date) {
  return `/dashboard/admin/abwesenheiten?date=${format(date, "yyyy-MM-dd")}`;
}

function startOfLocalDay(date: Date) {
  const nextDate = new Date(date);
  nextDate.setHours(0, 0, 0, 0);
  return nextDate;
}

function countByReason(items: AbsenceTableItem[]) {
  return items.reduce<Partial<Record<AbsenceReason, number>>>((acc, item) => {
    acc[item.reason] = (acc[item.reason] ?? 0) + 1;
    return acc;
  }, {});
}
