import React from "react";
import { Button } from "./button";
import { Calendar as CalendarPicker } from "./calendar";
import {
  Dialog,
  DialogClose,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "./dialog";
import { AddressAutocomplete } from "./form-primitives";
import { Label } from "./label";
import { RadioGroup, RadioGroupCard, RadioGroupItem } from "./radio-group";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "./select";
import { Input } from "./input";
import { Separator } from "./separator";
import { Textarea } from "./textarea";
import { Toggle } from "./toggle";
import { Badge } from "./badge";
import { Avatar, AvatarFallback } from "./avatar";
import { CalendarCheck, MapPin, Phone, Users, Video } from "lucide-react";
import { formatDateLong } from "../../lib/format-date";
import {
  AppointmentSlotSection,
  type AppointmentMeetingFormat,
  type AppointmentTimeSlot,
} from "./appointment-time-slot-picker";

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

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

export interface AppointmentClient {
  id: string;
  name: string;
  email: string;
  /** Phone numbers — for Call format. Multiple for Joint accounts. */
  phones?: string[];
  /** Account type — "Joint" shows multiple phones in Call format */
  accountType?: "Individual" | "Joint";
}

/**
 * Alias of AppointmentTimeSlot kept for backward compatibility.
 * Prefer importing AppointmentTimeSlot from appointment-time-slot-picker.
 */
export type AppointmentBookingSlot = AppointmentTimeSlot;

export type AppointmentOfflineLocation = "office" | "home" | "custom";

/**
 * Guest identity for **client / public booking mode**.
 *
 * - **Authenticated user** (e.g. app.wealthx.au): pass all three fields →
 *   the name/email/phone form is hidden and the values are submitted silently.
 * - **Public booking** (unauthenticated): omit this prop or leave fields
 *   empty → the form is shown so the guest can fill in their details.
 */
export interface AppointmentGuestInfo {
  name?: string;
  email?: string;
  phone?: string;
}

export interface AppointmentBookDialogProps {
  open: boolean;
  onOpenChange: (v: boolean) => void;
  /**
   * List of clients to search through.
   *
   * **Advisor mode (default):** provide a non-empty array — shows the client
   * search field and "New appointment" header copy.
   *
   * **Client mode:** omit or pass an empty array — hides the client search,
   * shows `advisorInfo` in the header instead, and changes the CTA copy to
   * "Book Appointment".
   */
  clients?: AppointmentClient[];
  /**
   * Fired when the user types in the client search field.
   * Use this to fetch clients from an API based on the query.
   * When omitted, clients are filtered locally by name/email.
   */
  onSearchClients?: (query: string) => void;
  /** True while a client search request is in-flight. */
  isSearchingClients?: boolean;
  /** True when more client results can be loaded. */
  hasMoreClients?: boolean;
  /** Fired when the user clicks "Load more" in the client dropdown. */
  onLoadMoreClients?: () => void;
  /** True while a load-more request is in-flight. */
  isLoadingMoreClients?: boolean;
  /**
   * Meeting type options. Omit or pass an empty array to hide the meeting
   * type field (useful in client mode where the type is implicit).
   */
  meetingTypes?: string[];
  amSlots: AppointmentTimeSlot[];
  pmSlots: AppointmentTimeSlot[];
  /**
   * 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 clients cannot select them.
   */
  schedule?: { day: string; enabled: boolean }[];
  /**
   * Advisor's office address pulled from company settings.
   * Shown as an offline location option.
   */
  advisorOfficeAddress?: string;
  /**
   * Client's home address from their CRM profile.
   * Shown as an offline location option when a client is selected.
   */
  clientHomeAddress?: string;
  /**
   * Advisor info shown in the dialog header when running in **client mode**
   * (i.e. when `clients` is omitted or empty).
   */
  advisorInfo?: { name: string; role: string; initials: string };
  /**
   * Pre-select a client by ID when the dialog opens (advisor mode only).
   * Used when rebooking from a cancelled appointment via `AppointmentDetailSheet`.
   */
  initialClientId?: string;
  /**
   * Pre-set meeting format when the dialog opens.
   *
   * @remarks Mount-time initialiser only.
   */
  defaultMeetingFormat?: AppointmentMeetingFormat;
  /**
   * Which online meeting platform(s) the advisor has integrated.
   *
   * - `"online"` — 1 email connected; show a generic "Online Meeting" button
   * - `"google-meet"` — show only Google Meet
   * - `"microsoft-teams"` — show only MS Teams
   * - `"any"` — 2 emails connected; show both Google Meet and MS Teams
   *
   * When omitted, no online option is shown (advisor has no email integration).
   */
  onlinePlatform?: AppointmentOnlinePlatform;
  /**
   * Guest identity for **client / public booking mode** only.
   * When all fields are provided the guest form is hidden; when any field is
   * missing the guest must fill in their own details.
   * Ignored in advisor mode.
   *
   * @remarks Mount-time initialiser only — state is seeded from this prop on
   * first render. Subsequent prop changes are ignored. Use the `key` prop to
   * force a full reset when `guestInfo` changes.
   */
  guestInfo?: AppointmentGuestInfo;
  onBook?: (data: {
    /** Empty string in client mode */
    clientId: string;
    /** Empty string when meetingTypes is omitted */
    meetingType: string;
    date: Date;
    slot: AppointmentTimeSlot;
    notes: string;
    meetingFormat: AppointmentMeetingFormat;
    offlineLocation?: AppointmentOfflineLocation;
    customAddress?: string;
    callPhone?: string;
    /** Client mode only — name of the guest/user making the booking */
    guestName?: string;
    /** Client mode only — email of the guest/user */
    guestEmail?: string;
    /** Client mode only — phone of the guest/user (optional) */
    guestPhone?: string;
  }) => void;
}

// ---------------------------------------------------------------------------
// Client search sub-component
// ---------------------------------------------------------------------------

function ClientSearch({
  clients,
  value,
  onValueChange,
  onSearch,
  isSearching,
  hasMore,
  onLoadMore,
  isLoadingMore,
}: {
  clients: AppointmentClient[];
  value: string | undefined;
  onValueChange: (id: string | undefined) => void;
  onSearch?: (query: string) => void;
  isSearching?: boolean;
  hasMore?: boolean;
  onLoadMore?: () => void;
  isLoadingMore?: boolean;
}) {
  const [query, setQuery] = React.useState("");
  const [open, setOpen] = React.useState(false);
  const selected = clients.find((c) => c.id === value);

  const filtered = onSearch
    ? clients
    : clients.filter((c) => {
        const q = query.toLowerCase();
        return (
          c.name.toLowerCase().includes(q) || c.email.toLowerCase().includes(q)
        );
      });

  return (
    <div className="relative">
      <Input
        value={selected ? selected.name : query}
        onChange={(e) => {
          const v = e.target.value;
          setQuery(v);
          if (selected) onValueChange(undefined);
          setOpen(v.length > 0);
          onSearch?.(v);
        }}
        onBlur={() => setTimeout(() => setOpen(false), 150)}
        placeholder="Search by name or email…"
        autoComplete="off"
      />
      {open && (filtered.length > 0 || query.length > 0 || isSearching) && (
        <div className="absolute z-50 mt-1 max-h-64 w-full overflow-y-auto border border-border bg-popover shadow-md">
          {isSearching ? (
            <p className="px-3 py-6 text-center text-sm text-muted-foreground">
              Searching...
            </p>
          ) : filtered.length === 0 ? (
            <p className="px-3 py-6 text-center text-sm text-muted-foreground">
              No clients found.
            </p>
          ) : (
            <>
              {filtered.map((c) => (
                <Button
                  key={c.id}
                  type="button"
                  variant="ghost"
                  className="h-auto w-full flex-col items-start gap-0.5 px-3 py-2 text-left hover:bg-primary/5"
                  onMouseDown={(e) => e.preventDefault()}
                  onClick={() => {
                    onValueChange(c.id);
                    setQuery("");
                    setOpen(false);
                  }}
                >
                  <span className="text-sm font-medium">{c.name}</span>
                  <span className="text-xs text-muted-foreground">
                    {c.email}
                  </span>
                </Button>
              ))}
              {hasMore && onLoadMore && (
                <Button
                  type="button"
                  variant="ghost"
                  size="sm"
                  className="w-full text-sm text-primary"
                  disabled={isLoadingMore}
                  onMouseDown={(e) => e.preventDefault()}
                  onClick={onLoadMore}
                >
                  {isLoadingMore ? "Loading..." : "Load more"}
                </Button>
              )}
            </>
          )}
        </div>
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Meeting format sub-component
// ---------------------------------------------------------------------------

interface FormatOption {
  value: AppointmentMeetingFormat;
  label: string;
  icon: React.ReactNode;
}

export type AppointmentOnlinePlatform =
  | "online"
  | "google-meet"
  | "microsoft-teams"
  | "any";

const FMT_CALL: FormatOption = {
  value: "call",
  label: "Call",
  icon: <Phone className="h-4 w-4" />,
};
const FMT_ONLINE: FormatOption = {
  value: "online",
  label: "Online Meeting",
  icon: <Video className="h-4 w-4" />,
};
const FMT_GOOGLE_MEET: FormatOption = {
  value: "google-meet",
  label: "Google Meet",
  icon: <Video className="h-4 w-4" />,
};
const FMT_MS_TEAMS: FormatOption = {
  value: "microsoft-teams",
  label: "MS Teams",
  icon: <Users className="h-4 w-4" />,
};
const FMT_OFFLINE: FormatOption = {
  value: "offline",
  label: "Offline Meeting",
  icon: <MapPin className="h-4 w-4" />,
};

function getFormatOptions(
  platform?: AppointmentOnlinePlatform,
): FormatOption[] {
  if (platform === "online") return [FMT_CALL, FMT_ONLINE, FMT_OFFLINE];
  if (platform === "google-meet")
    return [FMT_CALL, FMT_GOOGLE_MEET, FMT_OFFLINE];
  if (platform === "microsoft-teams")
    return [FMT_CALL, FMT_MS_TEAMS, FMT_OFFLINE];
  if (platform === "any")
    return [FMT_CALL, FMT_GOOGLE_MEET, FMT_MS_TEAMS, FMT_OFFLINE];
  return [FMT_CALL, FMT_OFFLINE];
}

function MeetingFormatSection({
  format,
  onFormatChange,
  offlineLocation,
  onOfflineLocationChange,
  customAddress,
  onCustomAddressChange,
  advisorOfficeAddress,
  clientHomeAddress,
  isClientMode,
  formatOptions,
}: {
  format: AppointmentMeetingFormat;
  onFormatChange: (f: AppointmentMeetingFormat) => void;
  offlineLocation: AppointmentOfflineLocation;
  onOfflineLocationChange: (l: AppointmentOfflineLocation) => void;
  customAddress: string;
  onCustomAddressChange: (v: string) => void;
  advisorOfficeAddress?: string;
  clientHomeAddress?: string;
  isClientMode?: boolean;
  formatOptions: FormatOption[];
}) {
  return (
    <div className="flex flex-col gap-2">
      <div className="grid grid-cols-1 gap-2 sm:grid-cols-3">
        {formatOptions.map((opt) => (
          <Toggle
            key={opt.value}
            variant="outline"
            pressed={format === opt.value}
            onPressedChange={() => onFormatChange(opt.value)}
            className="w-full gap-1.5"
          >
            {opt.icon}
            {opt.label}
          </Toggle>
        ))}
      </div>

      {format === "offline" && (
        <div className="flex flex-col gap-2 border border-border p-3">
          <p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
            Location
          </p>
          <RadioGroup
            value={offlineLocation}
            onValueChange={(v) =>
              onOfflineLocationChange(v as AppointmentOfflineLocation)
            }
            className="gap-2"
          >
            {advisorOfficeAddress && (
              <RadioGroupCard
                value="office"
                label="Adviser's Office"
                description={advisorOfficeAddress}
              />
            )}
            {clientHomeAddress && (
              <RadioGroupCard
                value="home"
                label={isClientMode ? "Home" : "Client's Home"}
                description={clientHomeAddress}
              />
            )}
            <RadioGroupCard
              value="custom"
              label="Custom address"
              description="Enter a specific location"
            />
          </RadioGroup>
          {offlineLocation === "custom" && (
            <AddressAutocomplete
              value={customAddress}
              onValueChange={onCustomAddressChange}
              placeholder="e.g. 123 Collins St, Melbourne VIC 3000"
            />
          )}
        </div>
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Booking confirmation sub-component (client mode only)
// ---------------------------------------------------------------------------

interface SubmittedBooking {
  advisorName?: string;
  date: Date;
  slotLabel: string;
}

function SummaryRow({
  label,
  value,
  border = true,
}: {
  label: string;
  value: React.ReactNode;
  border?: boolean;
}) {
  return (
    <div
      className={`flex items-center justify-between px-4 py-3 ${
        border ? "border-b border-border" : ""
      }`}
    >
      <span className="text-xs text-muted-foreground">{label}</span>
      {typeof value === "string" ? (
        <span className="text-xs font-medium">{value}</span>
      ) : (
        value
      )}
    </div>
  );
}

function BookingConfirmationScreen({
  booking,
  onDone,
}: {
  booking: SubmittedBooking;
  onDone: () => void;
}) {
  return (
    <div className="flex flex-col items-center gap-6 py-4 text-center">
      <div className="flex h-16 w-16 items-center justify-center bg-success/10">
        <CalendarCheck className="h-8 w-8 text-success" />
      </div>

      <div className="flex flex-col gap-1.5">
        <h3 className="text-lg font-semibold">Booking request sent!</h3>
        <p className="text-sm text-muted-foreground">
          Your adviser will review and confirm the appointment. You'll receive a
          notification once it's confirmed.
        </p>
      </div>

      <div className="w-full border border-border bg-muted/30 text-left">
        {booking.advisorName && (
          <SummaryRow label="Adviser" value={booking.advisorName} />
        )}
        <SummaryRow label="Date" value={formatDateLong(booking.date)} />
        <SummaryRow label="Time" value={booking.slotLabel} />
        <SummaryRow
          label="Status"
          value={<Badge variant="warning">Pending confirmation</Badge>}
          border={false}
        />
      </div>

      <Button className="w-full" onClick={onDone}>
        Done
      </Button>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------

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

// ---------------------------------------------------------------------------
// Main component
// ---------------------------------------------------------------------------

export function AppointmentBookDialog({
  open,
  onOpenChange,
  clients = [],
  onSearchClients,
  isSearchingClients,
  hasMoreClients,
  onLoadMoreClients,
  isLoadingMoreClients,
  meetingTypes = [],
  amSlots,
  pmSlots,
  onDateChange,
  schedule,
  advisorOfficeAddress,
  clientHomeAddress,
  advisorInfo,
  initialClientId,
  defaultMeetingFormat,
  onlinePlatform,
  guestInfo,
  onBook,
}: AppointmentBookDialogProps) {
  const isClientMode = clients.length === 0 && !onSearchClients;
  // Guest form is shown in client mode when at least one identity field is missing.
  const showGuestForm = isClientMode && !(guestInfo?.name && guestInfo?.email);

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

  // Stable "today" reference — avoids prop identity churn on CalendarPicker each render
  const today = React.useMemo(() => new Date(), []);

  const [clientId, setClientId] = React.useState<string | undefined>(undefined);
  const [meetingType, setMeetingType] = React.useState("");
  const [meetingFormat, setMeetingFormat] =
    React.useState<AppointmentMeetingFormat>(defaultMeetingFormat ?? "call");
  const [offlineLocation, setOfflineLocation] =
    React.useState<AppointmentOfflineLocation>(
      advisorOfficeAddress ? "office" : "custom",
    );
  const [customAddress, setCustomAddress] = React.useState("");
  const [date, setDate] = React.useState<Date | undefined>(() => new Date());
  const [selectedSlot, setSelectedSlot] = React.useState<
    AppointmentTimeSlot | undefined
  >(undefined);
  const [notes, setNotes] = React.useState("");
  const [selectedPhone, setSelectedPhone] = React.useState<string | undefined>(
    undefined,
  );

  // Guest identity — client / public booking mode only
  const [guestName, setGuestName] = React.useState(guestInfo?.name ?? "");
  const [guestEmail, setGuestEmail] = React.useState(guestInfo?.email ?? "");
  const [guestPhone, setGuestPhone] = React.useState(guestInfo?.phone ?? "");

  // null = form view; non-null = confirmation screen (client mode only)
  const [submittedBooking, setSubmittedBooking] =
    React.useState<SubmittedBooking | null>(null);

  const selectedClient = React.useMemo(
    () => clients.find((c) => c.id === clientId),
    [clients, clientId],
  );

  // Pre-select client when dialog opens with an initialClientId (e.g. rebook after cancellation)
  React.useEffect(() => {
    if (open && initialClientId) {
      setClientId(initialClientId);
    }
  }, [open, initialClientId]);

  React.useEffect(() => {
    setSelectedPhone(undefined);
  }, [clientId]);

  React.useEffect(() => {
    if (meetingFormat !== "call") {
      setSelectedPhone(undefined);
    }
  }, [meetingFormat]);

  const clientReady = isClientMode || !!clientId;
  const meetingTypeReady = meetingTypes.length === 0 || !!meetingType;
  const offlineReady =
    meetingFormat !== "offline" ||
    offlineLocation !== "custom" ||
    !!customAddress.trim();
  const guestReady =
    !showGuestForm || (!!guestName.trim() && !!guestEmail.trim());

  const canSubmit =
    clientReady &&
    meetingTypeReady &&
    !!date &&
    !!selectedSlot &&
    offlineReady &&
    guestReady;

  const handleOpenChange = (next: boolean) => {
    if (!next) {
      setClientId(undefined);
      setMeetingType("");
      setMeetingFormat(defaultMeetingFormat ?? "call");
      setOfflineLocation(advisorOfficeAddress ? "office" : "custom");
      setCustomAddress("");
      setDate(new Date());
      setSelectedSlot(undefined);
      setNotes("");
      setSelectedPhone(undefined);
      setGuestName(guestInfo?.name ?? "");
      setGuestEmail(guestInfo?.email ?? "");
      setGuestPhone(guestInfo?.phone ?? "");
      setSubmittedBooking(null);
    }
    onOpenChange(next);
  };

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogContent size="2xl" align="top">
        {submittedBooking ? (
          <BookingConfirmationScreen
            booking={submittedBooking}
            onDone={() => handleOpenChange(false)}
          />
        ) : (
          <>
            <DialogHeader>
              <DialogTitle>
                {isClientMode ? "Book an Appointment" : "New appointment"}
              </DialogTitle>
              <DialogDescription>
                {isClientMode
                  ? "Request a meeting with your adviser. They will confirm once the appointment is reviewed."
                  : "Book a meeting with a client. They will receive a confirmation email once the appointment is created."}
              </DialogDescription>

              {/* Advisor chip — client mode only */}
              {isClientMode && advisorInfo && (
                <div className="mt-3 flex items-center gap-3 border border-border bg-muted/30 px-3 py-2">
                  <Avatar className="h-8 w-8 shrink-0">
                    <AvatarFallback className="text-xs">
                      {advisorInfo.initials}
                    </AvatarFallback>
                  </Avatar>
                  <div className="flex flex-col gap-0.5">
                    <p className="text-sm font-medium">{advisorInfo.name}</p>
                    <p className="text-xs text-muted-foreground">
                      {advisorInfo.role}
                    </p>
                  </div>
                </div>
              )}
            </DialogHeader>

            <Separator />

            <div className="flex flex-col gap-4 overflow-y-auto max-h-[calc(90vh-200px)]">
              {!isClientMode && (
                <div className="flex flex-col gap-1.5">
                  <Label>Client</Label>
                  <ClientSearch
                    clients={clients}
                    value={clientId}
                    onValueChange={setClientId}
                    onSearch={onSearchClients}
                    isSearching={isSearchingClients}
                    hasMore={hasMoreClients}
                    onLoadMore={onLoadMoreClients}
                    isLoadingMore={isLoadingMoreClients}
                  />
                </div>
              )}

              {meetingTypes.length > 0 && (
                <div className="flex flex-col gap-1.5">
                  <Label htmlFor="book-apt-type">
                    {isClientMode ? "Appointment type" : "Meeting type"}
                  </Label>
                  <Select onValueChange={(v) => setMeetingType(v as string)}>
                    <SelectTrigger id="book-apt-type" className="w-full">
                      <SelectValue placeholder="Select meeting type…" />
                    </SelectTrigger>
                    <SelectContent>
                      {meetingTypes.map((t) => (
                        <SelectItem key={t} value={t}>
                          {t}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              )}

              {/* Guest identity — public booking only */}
              {showGuestForm && (
                <>
                  <div className="flex flex-col gap-1.5">
                    <Label htmlFor="guest-name">Full name</Label>
                    <Input
                      id="guest-name"
                      placeholder="Your full name"
                      value={guestName}
                      onChange={(e) => setGuestName(e.target.value)}
                      autoComplete="name"
                    />
                  </div>
                  <div className="flex flex-col gap-1.5">
                    <Label htmlFor="guest-email">Email</Label>
                    <Input
                      id="guest-email"
                      type="email"
                      placeholder="your@email.com"
                      value={guestEmail}
                      onChange={(e) => setGuestEmail(e.target.value)}
                      autoComplete="email"
                    />
                  </div>
                  <div className="flex flex-col gap-1.5">
                    <Label htmlFor="guest-phone">
                      Phone{" "}
                      <span className="font-normal text-muted-foreground">
                        (optional)
                      </span>
                    </Label>
                    <Input
                      id="guest-phone"
                      type="tel"
                      placeholder="+61 4XX XXX XXX"
                      value={guestPhone}
                      onChange={(e) => setGuestPhone(e.target.value)}
                      autoComplete="tel"
                    />
                  </div>
                </>
              )}

              <div className="flex flex-col gap-1.5">
                <Label>Meeting format</Label>
                <MeetingFormatSection
                  format={meetingFormat}
                  onFormatChange={setMeetingFormat}
                  offlineLocation={offlineLocation}
                  onOfflineLocationChange={setOfflineLocation}
                  customAddress={customAddress}
                  onCustomAddressChange={setCustomAddress}
                  advisorOfficeAddress={advisorOfficeAddress}
                  clientHomeAddress={clientHomeAddress}
                  isClientMode={isClientMode}
                  formatOptions={getFormatOptions(onlinePlatform)}
                />
              </div>

              {/* Phone selection — advisor mode, Call format, client has phones */}
              {!isClientMode &&
                meetingFormat === "call" &&
                selectedClient?.phones &&
                selectedClient.phones.length > 0 && (
                  <div className="flex flex-col gap-1.5">
                    <Label>
                      {selectedClient.accountType === "Joint"
                        ? "Select a contact number"
                        : "Phone number"}
                    </Label>
                    <RadioGroup
                      value={selectedPhone ?? ""}
                      onValueChange={(v) => setSelectedPhone(v as string)}
                      className="gap-1 border border-border p-3"
                    >
                      {selectedClient.phones.map((phone) => (
                        <div
                          key={phone}
                          className="flex items-center gap-3 p-2 hover:bg-muted/50"
                        >
                          <RadioGroupItem value={phone} id={`phone-${phone}`} />
                          <Label
                            htmlFor={`phone-${phone}`}
                            className="flex cursor-pointer items-center gap-2 font-normal"
                          >
                            <Phone className="h-4 w-4 text-muted-foreground" />
                            {phone}
                          </Label>
                        </div>
                      ))}
                    </RadioGroup>
                  </div>
                )}

              {/* Date + Time slot — side by side */}
              <div className="grid grid-cols-1 items-start gap-5 sm:grid-cols-[auto_1fr]">
                <div className="flex flex-col gap-1.5">
                  <Label>Date</Label>
                  <CalendarPicker
                    mode="single"
                    selected={date}
                    onSelect={(d) => {
                      setDate(d);
                      setSelectedSlot(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>
                <div className="flex flex-col gap-1.5">
                  <Label>Time slot</Label>
                  {date ? (
                    <div className="flex flex-col gap-3">
                      <p className="text-xs text-muted-foreground">
                        {date.toLocaleDateString("en-AU", {
                          weekday: "long",
                          day: "numeric",
                          month: "long",
                        })}
                      </p>
                      <AppointmentSlotSection
                        label="Morning"
                        slots={amSlots}
                        selectedSlotId={selectedSlot?.id}
                        onSelect={setSelectedSlot}
                      />
                      <AppointmentSlotSection
                        label="Afternoon"
                        slots={pmSlots}
                        selectedSlotId={selectedSlot?.id}
                        onSelect={setSelectedSlot}
                      />
                    </div>
                  ) : (
                    <p className="text-sm text-muted-foreground">
                      Select a date to see available slots.
                    </p>
                  )}
                </div>
              </div>

              {/* Notes */}
              <div className="flex flex-col gap-1.5">
                <Label htmlFor="book-apt-notes">
                  Notes{" "}
                  <span className="font-normal text-muted-foreground">
                    (optional)
                  </span>
                </Label>
                <Textarea
                  id="book-apt-notes"
                  placeholder={
                    isClientMode
                      ? "Let your adviser know what you'd like to discuss…"
                      : "e.g. Client wants to discuss refinancing their investment property…"
                  }
                  value={notes}
                  onChange={(e) => setNotes(e.target.value)}
                  className="w-full resize-none"
                  rows={2}
                />
              </div>
            </div>

            <DialogFooter>
              <DialogClose render={<Button variant="outline" />}>
                Cancel
              </DialogClose>
              <Button
                disabled={!canSubmit}
                onClick={() => {
                  if (canSubmit && date && selectedSlot) {
                    onBook?.({
                      clientId: clientId ?? "",
                      meetingType,
                      date,
                      slot: selectedSlot,
                      notes,
                      meetingFormat,
                      offlineLocation:
                        meetingFormat === "offline"
                          ? offlineLocation
                          : undefined,
                      customAddress:
                        meetingFormat === "offline" &&
                        offlineLocation === "custom"
                          ? customAddress
                          : undefined,
                      callPhone:
                        meetingFormat === "call" ? selectedPhone : undefined,
                      guestName: isClientMode
                        ? guestName.trim() || undefined
                        : undefined,
                      guestEmail: isClientMode
                        ? guestEmail.trim() || undefined
                        : undefined,
                      guestPhone: isClientMode
                        ? guestPhone.trim() || undefined
                        : undefined,
                    });
                    if (isClientMode) {
                      setSubmittedBooking({
                        advisorName: advisorInfo?.name,
                        date,
                        slotLabel: selectedSlot.label,
                      });
                    } else {
                      handleOpenChange(false);
                    }
                  }
                }}
              >
                {isClientMode ? "Book Appointment" : "Create appointment"}
              </Button>
            </DialogFooter>
          </>
        )}
      </DialogContent>
    </Dialog>
  );
}
