import React from "react";
import {
  Calendar as CalendarIcon,
  CalendarCheck,
  Clock,
  ExternalLink,
} from "lucide-react";
import { Avatar, AvatarFallback } from "./avatar";
import { Badge } from "./badge";
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 { safeWindowOpen } from "@/lib/safe-url";
import {
  AppointmentSlotSection,
  type AppointmentStatus,
  type AppointmentTimeSlot,
} from "./appointment-time-slot-picker";

// Re-export so consumers who import these types from this module still work
export type { AppointmentStatus } from "./appointment-time-slot-picker";
export type { AppointmentTimeSlot as AppointmentUpcomingSlot } from "./appointment-time-slot-picker";

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

/** @deprecated Use AppointmentStatus from appointment-time-slot-picker */
export type AppointmentUpcomingStatus = AppointmentStatus;

export interface AppointmentUpcomingAdvisor {
  name: string;
  role: string;
  company: string;
  avatarInitials: string;
}

export interface AppointmentUpcomingData {
  status: AppointmentStatus;
  advisor: AppointmentUpcomingAdvisor;
  /** Human-readable appointment type — shown as the card header title */
  appointmentType?: string;
  /** Display date string — e.g. "2026-04-22" */
  date: string;
  /** Display start time — e.g. "10:00 AM" */
  timeStart: string;
  /** Display end time — e.g. "10:30 AM" */
  timeEnd: string;
  /** Optional Google Calendar / iCal link shown on Confirmed appointments */
  calendarLink?: string;
  /** Original date before advisor rescheduled — only set when status is "rescheduled" */
  originalDate?: string;
  originalTimeStart?: string;
  originalTimeEnd?: string;
}

export interface AppointmentUpcomingCardProps {
  /** Pass null or undefined to show the empty state with a Book CTA */
  appointment?: AppointmentUpcomingData | null;
  /** AM time slots shown in the reschedule dialog */
  amSlots?: AppointmentTimeSlot[];
  /** PM time slots shown in the reschedule dialog */
  pmSlots?: AppointmentTimeSlot[];
  onBookAppointment?: () => void;
  /**
   * Called when the client submits a reschedule request.
   * @param date   The preferred date the client chose.
   * @param slot   The preferred time slot (undefined when no slot data is provided).
   * @param note   Optional note from the client.
   */
  onReschedule?: (
    date: Date,
    slot: AppointmentTimeSlot | undefined,
    note: string,
  ) => void;
  /**
   * Called when the client confirms cancellation.
   * @param reason Optional cancellation reason entered by the client.
   */
  onCancel?: (reason: string) => void;
  onAcceptReschedule?: () => void;
}

// ---------------------------------------------------------------------------
// AppointmentUpcomingCard
// ---------------------------------------------------------------------------

/**
 * Client-facing upcoming appointment card.
 *
 * Five states:
 * - **Empty** — no appointment; prompts user to book
 * - **Pending** — client booked, waiting for advisor confirmation
 * - **Confirmed** — advisor confirmed; shows Add to Calendar if link provided
 * - **Rescheduled** — advisor proposed a new time; Accept or Request Another Time
 * - **Cancelled** — advisor cancelled; prompts user to rebook
 */
export function AppointmentUpcomingCard({
  appointment,
  amSlots = [],
  pmSlots = [],
  onBookAppointment,
  onReschedule,
  onCancel,
  onAcceptReschedule,
}: AppointmentUpcomingCardProps) {
  // ── Dialog state ─────────────────────────────────────────────────────────────
  const [calendarDialogOpen, setCalendarDialogOpen] = React.useState(false);
  const [acceptDialogOpen, setAcceptDialogOpen] = React.useState(false);
  const [rescheduleDialogOpen, setRescheduleDialogOpen] = React.useState(false);
  const [cancelDialogOpen, setCancelDialogOpen] = React.useState(false);

  // Reschedule form
  const [rescheduleDate, setRescheduleDate] = React.useState<Date | undefined>(
    new Date(),
  );
  const [rescheduleSlot, setRescheduleSlot] = React.useState<
    AppointmentTimeSlot | undefined
  >(undefined);
  const [rescheduleNote, setRescheduleNote] = React.useState("");

  // Cancel form
  const [cancelReason, setCancelReason] = React.useState("");

  const resetRescheduleForm = () => {
    setRescheduleDate(new Date());
    setRescheduleSlot(undefined);
    setRescheduleNote("");
  };

  const hasSlotsData = amSlots.length > 0 || pmSlots.length > 0;
  const canSubmitReschedule = hasSlotsData
    ? !!rescheduleDate && !!rescheduleSlot
    : !!rescheduleDate;

  // ── Empty state ─────────────────────────────────────────────────────────────
  if (!appointment) {
    return (
      <div className="flex flex-col items-center gap-4 border border-border bg-card px-6 py-10 text-center">
        <div className="flex h-12 w-12 items-center justify-center bg-muted">
          <CalendarIcon className="h-6 w-6 text-muted-foreground" />
        </div>
        <div className="flex flex-col gap-1.5">
          <p className="text-base font-semibold">No upcoming appointments</p>
          <p className="text-sm text-muted-foreground">
            Schedule time with your adviser to discuss your financial goals.
          </p>
        </div>
        <Button onClick={onBookAppointment} className="w-full">
          Book an Appointment
        </Button>
      </div>
    );
  }

  const isPending = appointment.status === "pending";
  const isRescheduled = appointment.status === "rescheduled";
  const isCancelled = appointment.status === "cancelled";

  // ── Status badge ─────────────────────────────────────────────────────────────
  const statusBadge = (() => {
    if (isPending) return <Badge variant="warning">Pending</Badge>;
    if (isRescheduled) return <Badge variant="info">Rescheduled</Badge>;
    if (isCancelled) return <Badge variant="destructive">Cancelled</Badge>;
    return <Badge variant="success">Confirmed</Badge>;
  })();

  // ── Status notice banner ──────────────────────────────────────────────────────
  const noticeBanner = (() => {
    if (isPending) {
      return (
        <div className="bg-warning/10 px-5 py-3">
          <p className="text-sm text-foreground">
            Your booking request has been sent. Your adviser will confirm the
            appointment shortly.
          </p>
        </div>
      );
    }
    if (isRescheduled) {
      return (
        <div className="bg-info/10 px-5 py-3">
          <p className="text-sm text-foreground">
            Your adviser has proposed a new time. Please review and respond
            below.
          </p>
        </div>
      );
    }
    if (isCancelled) {
      return (
        <div className="bg-destructive/10 px-5 py-3">
          <p className="text-sm text-foreground">
            This appointment has been cancelled by your adviser.
          </p>
        </div>
      );
    }
    return null;
  })();

  const headerTitle = appointment.appointmentType
    ? appointment.appointmentType.toUpperCase()
    : "UPCOMING APPOINTMENT";

  // ── Filled state ──────────────────────────────────────────────────────────────
  return (
    <>
      <div className="flex flex-col border border-border bg-card">
        {/* Header */}
        <div className="flex items-center justify-between px-5 py-4">
          <div className="flex items-center gap-2">
            <CalendarCheck className="h-4 w-4 text-muted-foreground" />
            <p className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">
              {headerTitle}
            </p>
          </div>
          {statusBadge}
        </div>

        <Separator />

        {/* Advisor info */}
        <div className="flex items-center gap-4 px-5 py-4">
          <Avatar className="h-12 w-12 shrink-0">
            <AvatarFallback className="text-base">
              {appointment.advisor.avatarInitials}
            </AvatarFallback>
          </Avatar>
          <div className="flex flex-col gap-0.5">
            <p className="text-base font-semibold">
              {appointment.advisor.name}
            </p>
            <p className="text-sm text-muted-foreground">
              {appointment.advisor.role}
            </p>
            <p className="text-xs text-muted-foreground">
              {appointment.advisor.company}
            </p>
          </div>
        </div>

        <Separator />

        {/* Date/time */}
        <div className="flex flex-col gap-4 px-5 py-4">
          {isRescheduled ? (
            <>
              <div className="flex flex-col gap-2">
                <p className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
                  Original time
                </p>
                <div className="flex items-center gap-2.5 text-sm text-muted-foreground/50 line-through">
                  <CalendarIcon className="h-4 w-4 shrink-0" />
                  <span>{appointment.originalDate ?? appointment.date}</span>
                </div>
                <div className="flex items-center gap-2.5 text-sm text-muted-foreground/50 line-through">
                  <Clock className="h-4 w-4 shrink-0" />
                  <span>
                    {appointment.originalTimeStart ?? appointment.timeStart} –{" "}
                    {appointment.originalTimeEnd ?? appointment.timeEnd}
                  </span>
                </div>
              </div>
              <div className="flex flex-col gap-2">
                <p className="text-xs font-medium uppercase tracking-wide text-info">
                  New proposed time
                </p>
                <div className="flex items-center gap-2.5 text-sm text-foreground">
                  <CalendarIcon className="h-4 w-4 shrink-0" />
                  <span>{appointment.date}</span>
                </div>
                <div className="flex items-center gap-2.5 text-sm text-foreground">
                  <Clock className="h-4 w-4 shrink-0" />
                  <span>
                    {appointment.timeStart} – {appointment.timeEnd}
                  </span>
                </div>
              </div>
            </>
          ) : (
            <>
              <div
                className={`flex items-center gap-2.5 text-sm ${
                  isCancelled
                    ? "text-muted-foreground/50 line-through"
                    : "text-muted-foreground"
                }`}
              >
                <CalendarIcon className="h-4 w-4 shrink-0" />
                <span>{appointment.date}</span>
              </div>
              <div
                className={`flex items-center gap-2.5 text-sm ${
                  isCancelled
                    ? "text-muted-foreground/50 line-through"
                    : "text-muted-foreground"
                }`}
              >
                <Clock className="h-4 w-4 shrink-0" />
                <span>
                  {appointment.timeStart} – {appointment.timeEnd}
                </span>
              </div>
            </>
          )}
        </div>

        {/* Status notice */}
        {noticeBanner && (
          <>
            <Separator />
            {noticeBanner}
          </>
        )}

        <Separator />

        {/* Actions */}
        <div className="flex flex-col gap-2 px-5 py-4">
          {/* Confirmed — add to calendar */}
          {!isPending &&
            !isRescheduled &&
            !isCancelled &&
            appointment.calendarLink && (
              <Button
                className="w-full gap-2"
                onClick={() => setCalendarDialogOpen(true)}
              >
                <ExternalLink className="h-4 w-4" />
                Add to Calendar
              </Button>
            )}

          {/* Rescheduled — accept or request another time */}
          {isRescheduled && (
            <>
              <Button
                className="w-full"
                onClick={() => setAcceptDialogOpen(true)}
              >
                Accept New Time
              </Button>
              <Button
                variant="outline"
                className="w-full"
                onClick={() => {
                  resetRescheduleForm();
                  setRescheduleDialogOpen(true);
                }}
              >
                Request Another Time
              </Button>
            </>
          )}

          {/* Cancelled — rebook */}
          {isCancelled && (
            <Button className="w-full" onClick={onBookAppointment}>
              Book a New Appointment
            </Button>
          )}

          {/* Pending / Confirmed — reschedule + cancel */}
          {!isRescheduled && !isCancelled && (
            <>
              <Button
                variant="ghost"
                className="w-full"
                onClick={() => {
                  resetRescheduleForm();
                  setRescheduleDialogOpen(true);
                }}
              >
                Request Reschedule
              </Button>
              <Button
                variant="ghost"
                className="w-full text-destructive hover:text-destructive"
                onClick={() => {
                  setCancelReason("");
                  setCancelDialogOpen(true);
                }}
              >
                Cancel Booking
              </Button>
            </>
          )}
        </div>
      </div>

      {/* ── Accept New Time dialog ────────────────────────────────────────── */}
      <Dialog open={acceptDialogOpen} onOpenChange={setAcceptDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Accept New Time</DialogTitle>
            <DialogDescription>
              Confirm you want to accept{" "}
              <span className="font-medium text-foreground">
                {appointment.date}
              </span>{" "}
              from{" "}
              <span className="font-medium text-foreground">
                {appointment.timeStart} – {appointment.timeEnd}
              </span>{" "}
              as your new appointment time. Your adviser will be notified.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <DialogClose render={<Button variant="outline" />}>
              Keep Waiting
            </DialogClose>
            <Button
              onClick={() => {
                onAcceptReschedule?.();
                setAcceptDialogOpen(false);
              }}
            >
              Accept New Time
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* ── Add to Calendar dialog ─────────────────────────────────────────── */}
      <Dialog open={calendarDialogOpen} onOpenChange={setCalendarDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Add to Google Calendar</DialogTitle>
            <DialogDescription>
              You&apos;ll be taken to Google Calendar to save this appointment.
              Make sure you&apos;re signed in to the correct account.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <DialogClose render={<Button variant="outline" />}>
              Cancel
            </DialogClose>
            <Button
              className="gap-1.5"
              onClick={() => {
                if (appointment.calendarLink)
                  safeWindowOpen(appointment.calendarLink);
                setCalendarDialogOpen(false);
              }}
            >
              <ExternalLink className="h-4 w-4" />
              Open Google Calendar
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* ── Request Reschedule dialog ──────────────────────────────────────── */}
      <Dialog
        open={rescheduleDialogOpen}
        onOpenChange={(next) => {
          if (!next) resetRescheduleForm();
          setRescheduleDialogOpen(next);
        }}
      >
        <DialogContent size="2xl">
          <DialogHeader>
            <DialogTitle>Request Reschedule</DialogTitle>
            <DialogDescription>
              Choose your preferred date and time. Your adviser will review the
              request and confirm a new slot.
            </DialogDescription>
          </DialogHeader>

          <Separator />

          {/* Current booking */}
          <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 flex-wrap items-center gap-x-4 gap-y-1.5 border border-border bg-muted/30 px-3 py-2.5 text-sm text-muted-foreground">
              <span className="flex items-center gap-1.5">
                <CalendarIcon className="h-3.5 w-3.5 shrink-0" />
                {appointment.date}
              </span>
              <span className="flex items-center gap-1.5">
                <Clock className="h-3.5 w-3.5 shrink-0" />
                {appointment.timeStart} – {appointment.timeEnd}
              </span>
            </div>
          </div>

          <div className="grid grid-cols-1 items-start gap-5 sm:grid-cols-[auto_1fr]">
            {/* Date picker */}
            <div className="flex flex-col gap-1.5">
              <Label>Preferred date</Label>
              <CalendarPicker
                mode="single"
                selected={rescheduleDate}
                onSelect={(d) => {
                  setRescheduleDate(d);
                  setRescheduleSlot(undefined);
                }}
                captionLayout="label"
                fromDate={new Date()}
                disabled={{ before: new Date() }}
                className="border border-border"
              />
            </div>

            {/* Time slots */}
            <div className="flex flex-col gap-4">
              {hasSlotsData ? (
                rescheduleDate ? (
                  <>
                    <p className="text-sm font-semibold">Preferred time</p>
                    <AppointmentSlotSection
                      label="Morning"
                      slots={amSlots}
                      selectedSlotId={rescheduleSlot?.id}
                      onSelect={setRescheduleSlot}
                    />
                    <AppointmentSlotSection
                      label="Afternoon"
                      slots={pmSlots}
                      selectedSlotId={rescheduleSlot?.id}
                      onSelect={setRescheduleSlot}
                    />
                  </>
                ) : (
                  <div className="flex h-full flex-col items-center justify-center gap-2 py-8 text-center">
                    <p className="text-sm font-semibold">Preferred time</p>
                    <p className="text-xs text-muted-foreground">
                      Pick a date on the left to see available slots.
                    </p>
                  </div>
                )
              ) : null}
            </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. I have a conflict at this time and would like to move to a later slot…"
              value={rescheduleNote}
              onChange={(e) => setRescheduleNote(e.target.value)}
              className="w-full resize-none"
              rows={2}
            />
          </div>

          <DialogFooter>
            <DialogClose render={<Button variant="outline" />}>
              Cancel
            </DialogClose>
            <Button
              disabled={!canSubmitReschedule}
              onClick={() => {
                onReschedule?.(rescheduleDate!, rescheduleSlot, rescheduleNote);
                resetRescheduleForm();
                setRescheduleDialogOpen(false);
              }}
            >
              Submit Request
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* ── Cancel Booking dialog ──────────────────────────────────────────── */}
      <Dialog
        open={cancelDialogOpen}
        onOpenChange={(next) => {
          if (!next) setCancelReason("");
          setCancelDialogOpen(next);
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Cancel Booking</DialogTitle>
            <DialogDescription>
              Are you sure you want to cancel this appointment? Your adviser
              will be notified. This action cannot be undone.
            </DialogDescription>
          </DialogHeader>
          <div className="flex flex-col gap-1.5">
            <Label htmlFor="cancel-reason">
              Reason{" "}
              <span className="font-normal text-muted-foreground">
                (optional)
              </span>
            </Label>
            <Textarea
              id="cancel-reason"
              placeholder="e.g. I need to reschedule due to a conflict…"
              value={cancelReason}
              onChange={(e) => setCancelReason(e.target.value)}
              className="w-full resize-none"
              rows={2}
            />
          </div>
          <DialogFooter>
            <DialogClose render={<Button variant="outline" />}>
              Keep Booking
            </DialogClose>
            <Button
              variant="destructive"
              onClick={() => {
                onCancel?.(cancelReason);
                setCancelReason("");
                setCancelDialogOpen(false);
              }}
            >
              Cancel Booking
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
