import React from "react";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "./alert-dialog";
import { Button } from "./button";
import { Calendar as CalendarPicker } from "./calendar";
import {
  Dialog,
  DialogClose,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "./dialog";
import { Label } from "./label";
import { Separator } from "./separator";
import { Textarea } from "./textarea";
import { Calendar as CalendarIcon, Clock } from "lucide-react";
import {
  AppointmentSlotSection,
  type AppointmentTimeSlot,
} from "./appointment-time-slot-picker";

// Re-export for consumers who import AppointmentTimeSlot from this module
export type { AppointmentTimeSlot } from "./appointment-time-slot-picker";

// ---------------------------------------------------------------------------
// AppointmentConfirmDialog
// ---------------------------------------------------------------------------

export type AppointmentConfirmAction = "accept" | "decline";

export interface AppointmentConfirmDialogProps {
  open: boolean;
  onOpenChange: (v: boolean) => void;
  action: AppointmentConfirmAction;
  clientName: string;
  onConfirm: (reason?: string) => void;
}

export function AppointmentConfirmDialog({
  open,
  onOpenChange,
  action,
  clientName,
  onConfirm,
}: AppointmentConfirmDialogProps) {
  const isDecline = action === "decline";
  const [cancelReason, setCancelReason] = React.useState("");

  const handleOpenChange = (next: boolean) => {
    if (!next) setCancelReason("");
    onOpenChange(next);
  };

  return (
    <AlertDialog open={open} onOpenChange={handleOpenChange}>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>
            {isDecline
              ? "Decline this appointment?"
              : "Accept this appointment?"}
          </AlertDialogTitle>
          <AlertDialogDescription>
            {isDecline ? (
              <>
                This will cancel the appointment with{" "}
                <strong>{clientName}</strong> and notify them by email. This
                action cannot be undone.
              </>
            ) : (
              <>
                The appointment with <strong>{clientName}</strong> will be
                confirmed and they will be notified by email.
              </>
            )}
          </AlertDialogDescription>
        </AlertDialogHeader>

        {isDecline && (
          <div className="flex flex-col gap-1.5">
            <Label htmlFor="decline-reason">
              Reason{" "}
              <span className="font-normal text-muted-foreground">
                (optional)
              </span>
            </Label>
            <Textarea
              id="decline-reason"
              placeholder="e.g. Adviser is unavailable at this time…"
              value={cancelReason}
              onChange={(e) => setCancelReason(e.target.value)}
              className="w-full resize-none"
              rows={2}
            />
          </div>
        )}

        <AlertDialogFooter>
          <AlertDialogCancel>
            {isDecline ? "Keep appointment" : "Cancel"}
          </AlertDialogCancel>
          <AlertDialogAction
            onClick={() => onConfirm(isDecline ? cancelReason : undefined)}
            className={
              isDecline
                ? "bg-destructive text-destructive-foreground hover:bg-destructive/90"
                : undefined
            }
          >
            {isDecline ? "Decline appointment" : "Accept appointment"}
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

// ---------------------------------------------------------------------------
// AppointmentRescheduleDialog
// ---------------------------------------------------------------------------

export interface AppointmentRescheduleDialogProps {
  open: boolean;
  onOpenChange: (v: boolean) => void;
  amSlots: AppointmentTimeSlot[];
  pmSlots: AppointmentTimeSlot[];
  /** Current appointment date — shown as "Current booking" */
  currentDate?: string;
  currentTimeStart?: string;
  currentTimeEnd?: string;
  /**
   * Fired when the user selects a different date in the calendar.
   * Use this to fetch fresh `amSlots`/`pmSlots` for the new date.
   */
  onDateChange?: (date: Date) => void;
  /**
   * Advisor's weekly availability schedule. Days with `enabled: false` are
   * disabled in the date picker so the user cannot select them.
   */
  schedule?: { day: string; enabled: boolean }[];
  /** True while slots are being fetched for the selected date. */
  isLoadingSlots?: boolean;
  onReschedule: (date: Date, slot: AppointmentTimeSlot, note: string) => void;
}

const DAY_MAP: Record<string, number> = {
  Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6,
};

export function AppointmentRescheduleDialog({
  open,
  onOpenChange,
  amSlots,
  pmSlots,
  currentDate,
  currentTimeStart,
  currentTimeEnd,
  onDateChange,
  schedule,
  isLoadingSlots,
  onReschedule,
}: AppointmentRescheduleDialogProps) {
  const [date, setDate] = React.useState<Date | undefined>(new Date());
  const [slot, setSlot] = React.useState<AppointmentTimeSlot | undefined>();
  const [note, setNote] = React.useState("");

  const today = React.useMemo(() => new Date(), []);

  const disabledDayOfWeek = React.useMemo(
    () =>
      schedule
        ?.filter((d) => !d.enabled)
        .map((d) => DAY_MAP[d.day])
        .filter((n): n is number => n !== undefined),
    [schedule],
  );

  const handleOpenChange = (next: boolean) => {
    if (!next) {
      setDate(new Date());
      setSlot(undefined);
      setNote("");
    }
    onOpenChange(next);
  };

  const totalAvailable = [...amSlots, ...pmSlots].filter(
    (s) => s.available,
  ).length;

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogContent size="2xl">
        <DialogHeader>
          <DialogTitle>Propose New Time</DialogTitle>
          <DialogDescription>
            Select a new date and time slot. The client will be notified by
            email.
          </DialogDescription>
        </DialogHeader>

        <Separator />

        <div className="flex flex-col gap-4 overflow-y-auto max-h-[calc(90vh-200px)]">
        {/* Current booking */}
        {(currentDate || currentTimeStart) && (
          <div className="flex flex-col gap-1.5">
            <p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
              Current booking
            </p>
            <div className="flex items-center gap-4 border border-border bg-muted/30 px-3 py-2.5 text-sm text-muted-foreground">
              {currentDate && (
                <span className="flex items-center gap-1.5">
                  <CalendarIcon className="h-3.5 w-3.5 shrink-0" />
                  {currentDate}
                </span>
              )}
              {currentTimeStart && (
                <span className="flex items-center gap-1.5">
                  <Clock className="h-3.5 w-3.5 shrink-0" />
                  {currentTimeStart}
                  {currentTimeEnd ? ` – ${currentTimeEnd}` : ""}
                </span>
              )}
            </div>
          </div>
        )}

        <div className="grid grid-cols-[auto_1fr] items-start gap-5">
          {/* Date picker */}
          <div className="flex flex-col gap-1.5">
            <Label>New date</Label>
            <CalendarPicker
              mode="single"
              selected={date}
              onSelect={(d) => {
                setDate(d);
                setSlot(undefined);
                if (d) onDateChange?.(d);
              }}
              captionLayout="label"
              fromDate={today}
              disabled={
                disabledDayOfWeek && disabledDayOfWeek.length > 0
                  ? [{ before: today }, { dayOfWeek: disabledDayOfWeek }]
                  : { before: today }
              }
              className="border border-border"
            />
          </div>

          {/* Time slots */}
          <div className="flex flex-col gap-5">
            {date ? (
              isLoadingSlots ? (
                <div className="flex h-full flex-col items-center justify-center gap-2 py-8 text-center">
                  <p className="text-sm font-semibold">Loading slots…</p>
                  <p className="text-xs text-muted-foreground">
                    Fetching available times for the selected date.
                  </p>
                </div>
              ) : (
                <>
                  <div className="flex items-center justify-between">
                    <p className="text-sm font-semibold">Select a time slot</p>
                    <span className="text-xs text-muted-foreground">
                      {totalAvailable} available
                    </span>
                  </div>
                  <AppointmentSlotSection
                    label="Morning"
                    slots={amSlots}
                    selectedSlotId={slot?.id}
                    onSelect={setSlot}
                  />
                  <AppointmentSlotSection
                    label="Afternoon"
                    slots={pmSlots}
                    selectedSlotId={slot?.id}
                    onSelect={setSlot}
                  />
                </>
              )
            ) : (
              <div className="flex h-full flex-col items-center justify-center gap-2 py-8 text-center">
                <p className="text-sm font-semibold">Select a time slot</p>
                <p className="text-xs text-muted-foreground">
                  Pick a date on the left to see available slots.
                </p>
              </div>
            )}
          </div>
        </div>

        {/* Note — full width */}
        <div className="flex flex-col gap-1.5">
          <Label htmlFor="reschedule-note">
            Note{" "}
            <span className="font-normal text-muted-foreground">
              (optional)
            </span>
          </Label>
          <Textarea
            id="reschedule-note"
            placeholder="e.g. Rescheduling due to an internal conflict — apologies for the inconvenience…"
            value={note}
            onChange={(e) => setNote(e.target.value)}
            className="w-full resize-none"
            rows={2}
          />
        </div>
        </div>

        <DialogFooter>
          <DialogClose render={<Button variant="outline" />}>
            Cancel
          </DialogClose>
          <Button
            disabled={!date || !slot}
            onClick={() => {
              if (date && slot) {
                onReschedule(date, slot, note);
                handleOpenChange(false);
              }
            }}
          >
            Propose New Time
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
