"use client";

import { DutyAssignmentStatus, TerminStatus, TerminType } from "@prisma/client";
import { format } from "date-fns";
import { de } from "date-fns/locale";
import {
  AlertTriangle,
  Calendar,
  Clock,
  MapPin,
  MoreHorizontal,
  WashingMachine,
} from "lucide-react";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { AdminTerminModal } from "./admin-termin-modal";
import { TerminRequestModal } from "./termin-request-modal";

export type TerminListItemDto = {
  kind: "termin";
  id: string;
  title: string;
  description: string | null;
  type: TerminType;
  status: TerminStatus;
  startDate: Date;
  endDate: Date;
  allDay: boolean;
  mitbringselListEnabled: boolean;
  requiresRsvp: boolean;
  participantInfo: string | null;
  showParticipantInfo: boolean;
  mitbringselItems?: {
    id: string;
    userId: string;
    content: string;
    user: { firstName: string; lastName: string };
  }[];
};

export type DutyCalendarItemDto = {
  kind: "duty";
  id: string;
  title: string;
  familyName: string;
  status: DutyAssignmentStatus;
  startDate: Date;
  endDate: Date;
};

export type CalendarListItemDto = TerminListItemDto | DutyCalendarItemDto;

export function TerminList({
  termine,
  isAdmin,
}: {
  termine: CalendarListItemDto[];
  userId: string;
  isAdmin: boolean;
}) {
  if (termine.length === 0) {
    return (
      <Card>
        <CardContent className="flex max-h-[280px] min-h-[260px] flex-col items-center justify-center px-6 py-12 text-center">
          <div className="flex h-12 w-12 items-center justify-center rounded-2xl bg-[var(--accent-soft)] text-[var(--accent-deep)]">
            <Calendar className="h-6 w-6 [stroke-width:1.7]" />
          </div>
          <h3 className="mt-5 text-lg font-medium tracking-[-0.02em] text-[var(--ink)]">
            Keine Termine in diesem Zeitraum
          </h3>
          <p className="mt-2 max-w-md text-sm leading-6 text-[var(--ink-soft)]">
            Lege den ersten Termin an, damit Eltern planen können.
          </p>
          <div className="mt-5">
            {isAdmin ? (
              <AdminTerminModal triggerLabel="+ Termin anlegen" triggerClassName="" />
            ) : (
              <TerminRequestModal
                triggerLabel="+ Termin anlegen"
                triggerVariant="default"
                triggerClassName=""
              />
            )}
          </div>
        </CardContent>
      </Card>
    );
  }

  const groups = groupByMonth(termine);

  return (
    <div className="space-y-8">
      {groups.map((group) => (
        <section key={group.key}>
          <div className="mb-3 flex items-center justify-between gap-3">
            <h2 className="text-lg font-medium tracking-[-0.02em] text-[var(--ink)]">
              {group.label}
            </h2>
            <span className="rounded-full border border-[var(--hairline)] bg-[var(--surface-2)] px-2.5 py-1 text-[11px] font-semibold text-[var(--ink-soft)] tabular-nums">
              {group.items.length} {group.items.length === 1 ? "Termin" : "Termine"}
            </span>
          </div>
          <Card className="overflow-hidden p-0">
            <div className="divide-y divide-[var(--hairline-soft)]">
              {group.items.map((item) =>
                item.kind === "duty" ? (
                  <DutyRow key={`duty-${item.id}`} duty={item} />
                ) : (
                  <TerminRow key={`termin-${item.id}`} termin={item} />
                ),
              )}
            </div>
          </Card>
        </section>
      ))}
    </div>
  );
}

function DutyRow({ duty }: { duty: DutyCalendarItemDto }) {
  const color = "var(--good)";

  return (
    <div className="relative grid grid-cols-[56px_minmax(0,1fr)_auto] items-center gap-4 px-5 py-4 transition-colors hover:bg-[var(--surface-2)]">
      <div className="absolute inset-y-3 left-0 w-[3px] rounded-r-full" style={{ backgroundColor: color }} />
      <DateTile date={duty.startDate} />
      <div className="min-w-0">
        <h3 className="truncate text-[15px] font-semibold text-[var(--ink)]">
          {duty.title}
        </h3>
        <p className="mt-1 flex flex-wrap items-center gap-2 text-[13px] text-[var(--ink-soft)]">
          <Clock className="h-3.5 w-3.5 [stroke-width:1.7]" />
          {format(duty.startDate, "dd.MM.", { locale: de })} -{" "}
          {format(duty.endDate, "dd.MM.yyyy", { locale: de })}
          <WashingMachine className="ml-1 h-3.5 w-3.5 [stroke-width:1.7]" />
          {duty.familyName}
        </p>
      </div>
      <div className="flex items-center gap-2">
        <CategoryPill color={color}>Elterndienst</CategoryPill>
        <Button variant="ghost" size="icon" aria-label="Mehr Optionen">
          <MoreHorizontal className="h-4 w-4 [stroke-width:1.7]" />
        </Button>
      </div>
    </div>
  );
}

function TerminRow({ termin }: { termin: TerminListItemDto }) {
  const color = getTypeColor(termin.type);

  return (
    <Dialog>
      <div className="relative grid grid-cols-[56px_minmax(0,1fr)_auto] items-center gap-4 px-5 py-4 transition-colors hover:bg-[var(--surface-2)]">
        <div className="absolute inset-y-3 left-0 w-[3px] rounded-r-full" style={{ backgroundColor: color }} />
        <DateTile date={termin.startDate} />
        <div className="min-w-0">
          <div className="flex items-center gap-2">
            <h3 className="truncate text-[15px] font-semibold text-[var(--ink)]">
              {termin.title}
            </h3>
            {termin.status === TerminStatus.PENDING && (
              <Badge variant="warning">Ausstehend</Badge>
            )}
          </div>
          <p className="mt-1 flex flex-wrap items-center gap-2 text-[13px] text-[var(--ink-soft)]">
            <Clock className="h-3.5 w-3.5 [stroke-width:1.7]" />
            {formatTerminTime(termin)}
            <MapPin className="ml-1 h-3.5 w-3.5 [stroke-width:1.7]" />
            Kita
          </p>
        </div>
        <div className="flex items-center gap-2">
          <CategoryPill color={color}>{getTypeLabel(termin.type)}</CategoryPill>
          <DialogTrigger asChild>
            <Button variant="ghost" size="sm">
              Details
            </Button>
          </DialogTrigger>
          <Button variant="ghost" size="icon" aria-label="Mehr Optionen">
            <MoreHorizontal className="h-4 w-4 [stroke-width:1.7]" />
          </Button>
        </div>
      </div>

      <DialogContent>
        <DialogHeader>
          <DialogTitle>{termin.title}</DialogTitle>
          <DialogDescription>
            {format(termin.startDate, "PP", { locale: de })}
            {!termin.allDay &&
              ` · ${format(termin.startDate, "p", { locale: de })} - ${format(
                termin.endDate,
                "p",
                { locale: de },
              )}`}
          </DialogDescription>
        </DialogHeader>

        <div className="grid gap-4">
          <CategoryPill color={color}>{getTypeLabel(termin.type)}</CategoryPill>

          {termin.description ? (
            <p className="whitespace-pre-wrap text-sm leading-6 text-[var(--ink-soft)]">
              {termin.description}
            </p>
          ) : (
            <p className="text-sm italic text-[var(--ink-faint)]">
              Keine Beschreibung hinterlegt.
            </p>
          )}

          {termin.participantInfo && termin.showParticipantInfo && (
            <div className="rounded-lg border border-[var(--warn)] bg-[var(--warn-soft)] p-4 text-sm text-[var(--ink)]">
              <div className="mb-1 flex items-center gap-2 font-medium">
                <AlertTriangle className="h-4 w-4 text-[var(--warn)] [stroke-width:1.7]" />
                Wichtiger Hinweis für Teilnehmer
              </div>
              <p className="whitespace-pre-wrap">{termin.participantInfo}</p>
            </div>
          )}
        </div>
      </DialogContent>
    </Dialog>
  );
}

function DateTile({ date }: { date: Date }) {
  return (
    <div className="flex h-14 w-14 flex-col items-center justify-center rounded-lg border border-[var(--hairline)] bg-[var(--surface-2)]">
      <span className="text-[22px] font-medium leading-none tracking-[-0.02em] text-[var(--ink)] tabular-nums">
        {format(date, "d", { locale: de })}
      </span>
      <span className="mt-1 text-[10px] font-semibold uppercase text-[var(--ink-muted)] [letter-spacing:0.08em]">
        {format(date, "EEE", { locale: de })}
      </span>
    </div>
  );
}

function CategoryPill({
  color,
  children,
}: {
  color: string;
  children: React.ReactNode;
}) {
  return (
    <span
      className="inline-flex items-center gap-1.5 rounded-full border border-[var(--hairline)] bg-[var(--surface-2)] px-2.5 py-1 text-[11px] font-semibold text-[var(--ink-soft)]"
      style={{ color }}
    >
      <span className="h-1.5 w-1.5 rounded-full" style={{ backgroundColor: color }} />
      {children}
    </span>
  );
}

function groupByMonth(items: CalendarListItemDto[]) {
  const groups = new Map<string, { key: string; label: string; items: CalendarListItemDto[] }>();

  items.forEach((item) => {
    const key = format(item.startDate, "yyyy-MM");
    const label = format(item.startDate, "MMMM yyyy", { locale: de });
    const group = groups.get(key) ?? { key, label, items: [] };
    group.items.push(item);
    groups.set(key, group);
  });

  return Array.from(groups.values());
}

function formatTerminTime(termin: TerminListItemDto) {
  if (termin.allDay) return "ganztägig";
  return `${format(termin.startDate, "HH:mm", { locale: de })} - ${format(
    termin.endDate,
    "HH:mm",
    { locale: de },
  )}`;
}

function getTypeColor(type: TerminType): string {
  switch (type) {
    case TerminType.KITA_FEST:
    case TerminType.MITMACH_TAG:
      return "var(--good)";
    case TerminType.SCHLIESSTAG:
    case TerminType.TEAMTAG:
      return "var(--danger)";
    case TerminType.GEBURTSTAG_INTERN:
    case TerminType.GEBURTSTAG_EXTERN:
      return "oklch(0.50 0.10 320)";
    case TerminType.ELTERNABEND:
    case TerminType.MITGLIEDERVERSAMMLUNG:
    case TerminType.ELTERNCAFE:
      return "oklch(0.50 0.10 280)";
    default:
      return "var(--ink-muted)";
  }
}

function getTypeLabel(type: TerminType): string {
  switch (type) {
    case TerminType.KITA_FEST:
      return "Kita-Fest";
    case TerminType.MITMACH_TAG:
      return "Mitmach-Tag";
    case TerminType.SCHLIESSTAG:
      return "Schließtag";
    case TerminType.TEAMTAG:
      return "Teamtag";
    case TerminType.ELTERNABEND:
      return "Elternabend";
    case TerminType.MITGLIEDERVERSAMMLUNG:
      return "Mitgliederversammlung";
    case TerminType.ELTERNCAFE:
      return "Elterncafe";
    case TerminType.GEBURTSTAG_INTERN:
      return "Geburtstag";
    case TerminType.GEBURTSTAG_EXTERN:
      return "Raumanfrage";
    default:
      return "Sonstiges";
  }
}
