"use client";

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

import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { MitbringselList } from "./mitbringsel-list";
import { toggleMitbringselList } from "../actions";
import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";
import { useTransition } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";

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,
  userId,
  isAdmin,
}: {
  termine: CalendarListItemDto[];
  userId: string;
  isAdmin: boolean;
}) {
  if (termine.length === 0) {
    return (
      <div className="flex flex-col items-center justify-center rounded-lg border border-dashed p-8 text-center animate-in fade-in-50">
        <div className="mx-auto flex max-w-[420px] flex-col items-center justify-center text-center">
          <Calendar className="h-10 w-10 text-muted-foreground mb-4" />
          <h3 className="mt-4 text-lg font-semibold">Keine Termine</h3>
          <p className="mb-4 mt-2 text-sm text-muted-foreground">
            Es stehen aktuell keine Termine an.
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
      {termine.map((termin) => (
        termin.kind === "duty" ? (
          <DutyCard key={`duty-${termin.id}`} duty={termin} />
        ) : (
          <TerminCard
            key={`termin-${termin.id}`}
            termin={termin}
            userId={userId}
            isAdmin={isAdmin}
          />
        )
      ))}
    </div>
  );
}

function DutyCard({ duty }: { duty: DutyCalendarItemDto }) {
  return (
    <Card className="flex flex-col overflow-hidden border-emerald-200 bg-emerald-50/60">
      <CardHeader className="pb-3">
        <div className="mb-2 flex items-start justify-between gap-2">
          <Badge className="border-transparent bg-emerald-600 text-white hover:bg-emerald-700">
            Elterndienst
          </Badge>
        </div>
        <CardTitle className="line-clamp-2 leading-tight">
          {duty.title}
        </CardTitle>
        <CardDescription className="mt-1 flex items-center gap-1 text-sm">
          <Clock className="h-3.5 w-3.5" />
          {format(duty.startDate, "dd.MM.", { locale: de })} -{" "}
          {format(duty.endDate, "dd.MM.yyyy", { locale: de })}
        </CardDescription>
      </CardHeader>

      <CardContent className="flex-1 pb-4">
        <div className="flex items-start gap-2 text-sm text-emerald-900">
          <WashingMachine className="mt-0.5 h-4 w-4 shrink-0" />
          <p>
            Eingeteilt: <span className="font-medium">{duty.familyName}</span>
          </p>
        </div>
      </CardContent>
    </Card>
  );
}

function TerminCard({
  termin,
  userId,
  isAdmin,
}: {
  termin: TerminListItemDto;
  userId: string;
  isAdmin: boolean;
}) {
  const [isPending, startTransition] = useTransition();

  const handleToggleMitbringsel = (enabled: boolean) => {
    startTransition(async () => {
      const result = await toggleMitbringselList(termin.id, enabled);
      if (result.error) {
        toast.error(result.error);
      } else {
        toast.success(
          enabled
            ? "Mitbring-Liste aktiviert"
            : "Mitbring-Liste deaktiviert"
        );
      }
    });
  };

  return (
    <Card className="flex flex-col overflow-hidden relative">
      {termin.status === TerminStatus.PENDING && (
        <div className="absolute top-0 right-0 bg-yellow-500 text-white text-xs font-bold px-2 py-1 rounded-bl-lg z-10">
          Ausstehend
        </div>
      )}
      <CardHeader className="pb-3">
        <div className="flex justify-between items-start mb-2 gap-2">
          <Badge variant={getBadgeVariant(termin.type)} className={getBadgeColor(termin.type)}>
            {getTypeLabel(termin.type)}
          </Badge>
        </div>
        <CardTitle className="line-clamp-2 leading-tight">{termin.title}</CardTitle>
        <CardDescription className="flex items-center gap-1 mt-1 text-sm">
          <Clock className="h-3.5 w-3.5" />
          {format(termin.startDate, "PP", { locale: de })}
          {!termin.allDay && (
            <>
              {" • "}
              {format(termin.startDate, "p", { locale: de })} -{" "}
              {format(termin.endDate, "p", { locale: de })}
            </>
          )}
        </CardDescription>
      </CardHeader>

      <CardContent className="flex-1 pb-4">
        {termin.description && (
          <div className="flex items-start gap-2 text-sm text-muted-foreground mt-2">
            <AlignLeft className="h-4 w-4 shrink-0 mt-0.5" />
            <p className="line-clamp-3 whitespace-pre-wrap">{termin.description}</p>
          </div>
        )}

        <TerminDetailDialog termin={termin} />

        {/* Admin Toggle for Mitbringsel-List */}
        {isAdmin && termin.status === TerminStatus.CONFIRMED && (
          <div className="flex items-center space-x-2 mt-6 pt-4 border-t">
            <Switch
              id={`mitbringsel-${termin.id}`}
              checked={termin.mitbringselListEnabled}
              onCheckedChange={handleToggleMitbringsel}
              disabled={isPending}
            />
            <Label htmlFor={`mitbringsel-${termin.id}`} className="text-xs">
              Mitbring-Liste aktiv
            </Label>
          </div>
        )}

        {/* Mitbringsel-List UI */}
        {termin.mitbringselListEnabled && termin.status === TerminStatus.CONFIRMED && (
          <div className="mt-4">
            <MitbringselList
              terminId={termin.id}
              items={termin.mitbringselItems || []}
              currentUserId={userId}
              isAdmin={isAdmin}
            />
          </div>
        )}
      </CardContent>
    </Card>
  );
}

function TerminDetailDialog({ termin }: { termin: TerminListItemDto }) {
  return (
    <Dialog>
      <DialogTrigger asChild>
        <Button variant="outline" size="sm" className="mt-4">
          Details
        </Button>
      </DialogTrigger>
      <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">
          <Badge variant={getBadgeVariant(termin.type)} className={getBadgeColor(termin.type)}>
            {getTypeLabel(termin.type)}
          </Badge>

          {termin.description ? (
            <p className="whitespace-pre-wrap text-sm text-muted-foreground">
              {termin.description}
            </p>
          ) : (
            <p className="text-sm text-muted-foreground">
              Keine Beschreibung hinterlegt.
            </p>
          )}

          {termin.participantInfo && termin.showParticipantInfo && (
            <div className="rounded-md border border-yellow-300 bg-yellow-50 p-4 text-sm text-yellow-950">
              <div className="mb-1 flex items-center gap-2 font-medium">
                <AlertTriangle className="h-4 w-4 text-yellow-700" />
                Wichtiger Hinweis für Teilnehmer
              </div>
              <p className="whitespace-pre-wrap">{termin.participantInfo}</p>
            </div>
          )}
        </div>
      </DialogContent>
    </Dialog>
  );
}

function getBadgeVariant(type: TerminType): "default" | "secondary" | "destructive" | "outline" {
  switch (type) {
    case TerminType.KITA_FEST:
    case TerminType.MITMACH_TAG:
      return "default";
    case TerminType.SCHLIESSTAG:
    case TerminType.TEAMTAG:
      return "destructive";
    case TerminType.GEBURTSTAG_INTERN:
    case TerminType.GEBURTSTAG_EXTERN:
    case TerminType.ELTERNABEND:
    case TerminType.MITGLIEDERVERSAMMLUNG:
    case TerminType.ELTERNCAFE:
      return "secondary";
    default:
      return "outline";
  }
}

function getBadgeColor(type: TerminType): string {
  switch (type) {
    case TerminType.KITA_FEST:
    case TerminType.MITMACH_TAG:
      return "bg-amber-500 hover:bg-amber-600 text-white border-transparent";
    case TerminType.SCHLIESSTAG:
    case TerminType.TEAMTAG:
      return "bg-rose-500 hover:bg-rose-600 text-white border-transparent";
    case TerminType.GEBURTSTAG_INTERN:
    case TerminType.GEBURTSTAG_EXTERN:
      return "bg-blue-500 hover:bg-blue-600 text-white border-transparent";
    case TerminType.ELTERNABEND:
    case TerminType.MITGLIEDERVERSAMMLUNG:
    case TerminType.ELTERNCAFE:
      return "bg-purple-500 hover:bg-purple-600 text-white border-transparent";
    default:
      return "bg-slate-200 text-slate-800 border-slate-300 dark:bg-slate-800 dark:text-slate-200 dark:border-slate-700";
  }
}

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 (Kita geschlossen)";
    case TerminType.ELTERNABEND:
      return "Elternabend";
    case TerminType.MITGLIEDERVERSAMMLUNG:
      return "Mitgliederversammlung";
    case TerminType.ELTERNCAFE:
      return "Elterncafe";
    case TerminType.GEBURTSTAG_INTERN:
      return "Geburtstag (Intern)";
    case TerminType.GEBURTSTAG_EXTERN:
      return "Raumanfrage (Extern)";
    default:
      return "Sonstiges";
  }
}
