import React from "react";
import { Avatar, AvatarFallback } from "./avatar";
import { Badge } from "./badge";
import { Button } from "./button";
import { Separator } from "./separator";
import { Sheet, SheetContent } from "./sheet";
import {
  AppointmentConfirmAction,
  AppointmentConfirmDialog,
  AppointmentRescheduleDialog,
} from "./appointment-action-dialogs";
import type {
  AppointmentMeetingFormat,
  AppointmentStatus,
  AppointmentTimeSlot,
} from "./appointment-time-slot-picker";
import {
  AlertCircle,
  Calendar,
  CalendarClock,
  Check,
  Circle,
  CircleCheck,
  CircleUser,
  Clock,
  ExternalLink,
  FileText,
  Mail,
  MapPin,
  Phone,
  RefreshCw,
  Sparkles,
  Users,
  Video,
  X,
} from "lucide-react";

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

export interface AppointmentMeetingActionItem {
  label: string;
  done?: boolean;
}

/** AI-generated recap of a completed meeting, stored on the booking. */
export interface AppointmentMeetingSummary {
  /** Short recap of what was discussed. */
  summary?: string;
  /** Follow-up items, optionally marked done. */
  actionItems?: AppointmentMeetingActionItem[];
}

export interface AppointmentDetailItem {
  id: string;
  status: AppointmentStatus;
  clientName: string;
  clientAvatarInitials: string;
  /** Client ID — used to pre-select client when rebooking after cancellation */
  clientId?: string;
  date: string;
  timeStart: string;
  timeEnd: string;
  notes?: string;
  /** Reason provided when the appointment was cancelled */
  cancelReason?: string;
  /** How the meeting is conducted */
  meetingFormat?: AppointmentMeetingFormat;
  /** Formatted location string — shown for offline meetings */
  meetingLocation?: string;
  /** Phone number — shown for call meetings */
  callPhone?: string;
  /** Join URL — shown for google-meet and microsoft-teams meetings */
  meetingLink?: string;
  /** AI meeting summary — shown once the meeting has been recorded and summarised */
  meetingSummary?: AppointmentMeetingSummary;
}

export type LoanApplicationStatus =
  | "finished"
  | "in-progress"
  | "sent-request"
  | "not-start";

/** Extra client profile fields not stored on the appointment itself */
export interface AppointmentClientProfile {
  phone?: string;
  email?: string;
  accountType?: "Individual" | "Joint";
  loanApplicationStatus?: LoanApplicationStatus;
}

export interface AppointmentDetailSheetProps {
  appointment: AppointmentDetailItem | undefined;
  open: boolean;
  onOpenChange: (v: boolean) => void;
  clientProfile?: AppointmentClientProfile;
  amSlots: AppointmentTimeSlot[];
  pmSlots: AppointmentTimeSlot[];
  /**
   * Fired when the user selects a different date in the reschedule dialog.
   * 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 reschedule date picker.
   */
  schedule?: { day: string; enabled: boolean }[];
  /** True while slots are being fetched for the selected date. */
  isLoadingSlots?: boolean;
  onAccept?: (id: string) => void;
  onDecline?: (id: string) => void;
  onReschedule?: (
    id: string,
    date: Date,
    slot: AppointmentTimeSlot,
    note: string
  ) => void;
  /** Called when "Book a New Appointment" is clicked on a cancelled appointment */
  onBookNew?: (clientId?: string) => void;
}

// ---------------------------------------------------------------------------
// Status config
// ---------------------------------------------------------------------------

const STATUS_CONFIG: Record<
  AppointmentStatus,
  {
    variant: "warning" | "success" | "destructive" | "info";
    label: string;
    icon: React.ReactNode;
  }
> = {
  pending: {
    variant: "warning",
    label: "Pending",
    icon: <CalendarClock size={12} />,
  },
  confirmed: {
    variant: "success",
    label: "Confirmed",
    icon: <Check size={12} />,
  },
  cancelled: {
    variant: "destructive",
    label: "Cancelled",
    icon: <X size={12} />,
  },
  rescheduled: {
    variant: "info",
    label: "Rescheduled",
    icon: <RefreshCw size={12} />,
  },
};

// ---------------------------------------------------------------------------
// Meeting format config
// ---------------------------------------------------------------------------

const ICON_CLASS = "mt-0.5 h-4 w-4 shrink-0 text-muted-foreground";

const MEETING_FORMAT_META: Record<
  AppointmentMeetingFormat,
  { icon: React.ReactNode; label: string }
> = {
  call: { icon: <Phone className={ICON_CLASS} />, label: "Phone Call" },
  "google-meet": {
    icon: <Video className={ICON_CLASS} />,
    label: "Google Meet",
  },
  "microsoft-teams": {
    icon: <Users className={ICON_CLASS} />,
    label: "Microsoft Teams",
  },
  online: { icon: <Video className={ICON_CLASS} />, label: "Online Meeting" },
  offline: { icon: <MapPin className={ICON_CLASS} />, label: "In Person" },
};

/** Formats that use a join link rather than a phone number or physical location */
const ONLINE_FORMATS = new Set<AppointmentMeetingFormat>([
  "google-meet",
  "microsoft-teams",
  "online",
]);

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------

export function AppointmentDetailSheet({
  appointment,
  open,
  onOpenChange,
  clientProfile,
  amSlots,
  pmSlots,
  onDateChange,
  schedule,
  isLoadingSlots,
  onAccept,
  onDecline,
  onReschedule,
  onBookNew,
}: AppointmentDetailSheetProps) {
  const [confirmAction, setConfirmAction] =
    React.useState<AppointmentConfirmAction | null>(null);
  const [rescheduleOpen, setRescheduleOpen] = React.useState(false);

  if (!appointment) return null;

  const { variant, label, icon } = STATUS_CONFIG[appointment.status];
  const isCancelled = appointment.status === "cancelled";
  const isConfirmed = appointment.status === "confirmed";
  const fmt = appointment.meetingFormat;
  const meetingMeta = fmt ? MEETING_FORMAT_META[fmt] : undefined;

  return (
    <>
      <Sheet open={open} onOpenChange={onOpenChange}>
        <SheetContent
          side="right"
          className="flex w-[440px] flex-col gap-0 overflow-y-auto p-0"
        >
          {/* ── Header: avatar + name/badge + action buttons ── */}
          <div className="border-b border-border px-6 py-5">
            <div className="flex items-start gap-4">
              <Avatar className="h-12 w-12 shrink-0">
                <AvatarFallback className="text-base">
                  {appointment.clientAvatarInitials}
                </AvatarFallback>
              </Avatar>
              <div className="flex min-w-0 flex-1 flex-col gap-1">
                <p className="text-lg font-semibold leading-tight">
                  {appointment.clientName}
                </p>
                <Badge variant={variant} className="w-fit">
                  {icon}
                  {label}
                </Badge>
              </div>
            </div>

            {/* Action buttons */}
            <div className="mt-4 flex gap-2">
              {isCancelled ? (
                <Button
                  size="sm"
                  className="w-full"
                  onClick={() => onBookNew?.(appointment.clientId)}
                >
                  Book a New Appointment
                </Button>
              ) : (
                <>
                  <Button
                    size="sm"
                    disabled={isConfirmed}
                    onClick={() => setConfirmAction("accept")}
                    className="flex-1 gap-1.5"
                  >
                    <Check className="h-3.5 w-3.5" />
                    Accept
                  </Button>
                  <Button
                    size="sm"
                    variant="ghost"
                    onClick={() => setConfirmAction("decline")}
                    className="flex-1 gap-1.5 text-destructive hover:text-destructive"
                  >
                    <X className="h-3.5 w-3.5" />
                    Decline
                  </Button>
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => setRescheduleOpen(true)}
                    className="flex-1 gap-1.5"
                  >
                    <RefreshCw className="h-3.5 w-3.5" />
                    Reschedule
                  </Button>
                </>
              )}
            </div>
          </div>

          {/* ── Appointment details ── */}
          <div className="flex flex-col gap-4 px-6 py-5">
            <div className="flex items-center gap-3 text-sm">
              <Calendar className="h-4 w-4 shrink-0 text-muted-foreground" />
              <span className="font-medium">{appointment.date}</span>
            </div>
            <div className="flex items-center gap-3 text-sm">
              <Clock className="h-4 w-4 shrink-0 text-muted-foreground" />
              <span className="font-medium">
                {appointment.timeStart} – {appointment.timeEnd}
              </span>
            </div>

            {fmt && meetingMeta && (
              <div className="flex items-start gap-3 text-sm">
                {meetingMeta.icon}
                <div className="flex flex-col gap-0.5">
                  <span className="font-medium">{meetingMeta.label}</span>
                  {fmt === "call" && appointment.callPhone && (
                    <span className="text-muted-foreground">
                      {appointment.callPhone}
                    </span>
                  )}
                  {ONLINE_FORMATS.has(fmt) && appointment.meetingLink && (
                    <a
                      href={appointment.meetingLink}
                      target="_blank"
                      rel="noreferrer"
                      className="flex items-center gap-1 text-primary hover:underline"
                    >
                      <ExternalLink className="h-3 w-3" />
                      Join Meeting
                    </a>
                  )}
                  {fmt === "offline" && appointment.meetingLocation && (
                    <span className="text-muted-foreground">
                      {appointment.meetingLocation}
                    </span>
                  )}
                </div>
              </div>
            )}
          </div>

          {/* ── Client profile ── */}
          {clientProfile &&
            (clientProfile.phone !== undefined ||
              clientProfile.email !== undefined ||
              clientProfile.accountType !== undefined ||
              clientProfile.loanApplicationStatus !== undefined) && (
              <>
                <Separator />
                <div className="flex flex-col gap-3 px-6 py-5">
                  <p className="text-sm font-semibold">Client Profile</p>
                  <div className="flex flex-col gap-2">
                    {clientProfile.phone && (
                      <div className="flex items-center gap-3 text-sm">
                        <Phone className="h-4 w-4 shrink-0 text-muted-foreground" />
                        <span className="text-muted-foreground">
                          {clientProfile.phone}
                        </span>
                      </div>
                    )}
                    {clientProfile.email && (
                      <div className="flex items-center gap-3 text-sm">
                        <Mail className="h-4 w-4 shrink-0 text-muted-foreground" />
                        <span className="text-muted-foreground">
                          {clientProfile.email}
                        </span>
                      </div>
                    )}
                    {clientProfile.accountType !== undefined && (
                      <div className="flex items-center justify-between text-sm">
                        <span className="text-muted-foreground">
                          Account type
                        </span>
                        <div className="flex items-center gap-1.5">
                          {clientProfile.accountType === "Joint" ? (
                            <Users className="h-3.5 w-3.5 text-muted-foreground" />
                          ) : (
                            <CircleUser className="h-3.5 w-3.5 text-muted-foreground" />
                          )}
                          <span className="font-medium">
                            {clientProfile.accountType}
                          </span>
                        </div>
                      </div>
                    )}
                    {clientProfile.loanApplicationStatus !== undefined && (
                      <div className="flex items-center justify-between text-sm">
                        <span className="text-muted-foreground">
                          Loan application
                        </span>
                        <div className="flex items-center gap-1.5">
                          <FileText className="h-3.5 w-3.5 text-muted-foreground" />
                          {clientProfile.loanApplicationStatus ===
                            "finished" && (
                            <Badge variant="success" className="text-[10px]">
                              Finished
                            </Badge>
                          )}
                          {clientProfile.loanApplicationStatus ===
                            "in-progress" && (
                            <Badge variant="warning" className="text-[10px]">
                              In Progress
                            </Badge>
                          )}
                          {clientProfile.loanApplicationStatus ===
                            "sent-request" && (
                            <Badge variant="info" className="text-[10px]">
                              Sent Request
                            </Badge>
                          )}
                          {clientProfile.loanApplicationStatus ===
                            "not-start" && (
                            <Badge variant="secondary" className="text-[10px]">
                              Not Started
                            </Badge>
                          )}
                        </div>
                      </div>
                    )}
                  </div>
                </div>
              </>
            )}

          {/* ── Meeting Summary ── */}
          {appointment.meetingSummary &&
            (appointment.meetingSummary.summary ||
              (appointment.meetingSummary.actionItems?.length ?? 0) > 0) && (
              <>
                <Separator />
                <div className="flex flex-col gap-3 px-6 py-5">
                  <div className="flex items-center gap-2">
                    <Sparkles className="h-4 w-4 text-muted-foreground" />
                    <p className="text-sm font-semibold">Meeting Summary</p>
                  </div>
                  {appointment.meetingSummary.summary && (
                    <p className="text-sm text-muted-foreground">
                      {appointment.meetingSummary.summary}
                    </p>
                  )}
                  {(appointment.meetingSummary.actionItems?.length ?? 0) > 0 && (
                    <div className="flex flex-col gap-2">
                      <p className="text-sm font-medium">Action items</p>
                      <div className="flex flex-col gap-1.5">
                        {appointment.meetingSummary.actionItems?.map(
                          (item, i) => (
                            <div
                              key={i}
                              className="flex items-start gap-2 text-sm"
                            >
                              {item.done ? (
                                <CircleCheck className="mt-0.5 h-4 w-4 shrink-0 text-muted-foreground" />
                              ) : (
                                <Circle className="mt-0.5 h-4 w-4 shrink-0 text-muted-foreground" />
                              )}
                              <span
                                className={
                                  item.done
                                    ? "text-muted-foreground line-through"
                                    : ""
                                }
                              >
                                {item.label}
                              </span>
                            </div>
                          )
                        )}
                      </div>
                    </div>
                  )}
                </div>
              </>
            )}

          {/* ── Notes ── */}
          {appointment.notes && (
            <>
              <Separator />
              <div className="flex flex-col gap-2 px-6 py-5">
                <div className="flex items-center gap-2">
                  <FileText className="h-4 w-4 text-muted-foreground" />
                  <p className="text-sm font-semibold">Notes</p>
                </div>
                <p className="text-sm text-muted-foreground">
                  {appointment.notes}
                </p>
              </div>
            </>
          )}

          {/* ── Cancellation Reason ── */}
          {appointment.cancelReason && (
            <>
              <Separator />
              <div className="flex flex-col gap-2 px-6 py-5">
                <div className="flex items-center gap-2">
                  <AlertCircle className="h-4 w-4 text-destructive" />
                  <p className="text-sm font-semibold">Cancellation Reason</p>
                </div>
                <p className="text-sm text-muted-foreground">
                  {appointment.cancelReason}
                </p>
              </div>
            </>
          )}
        </SheetContent>
      </Sheet>

      {/* Dialogs rendered outside Sheet to avoid z-index issues */}
      <AppointmentConfirmDialog
        open={confirmAction !== null}
        onOpenChange={(v) => !v && setConfirmAction(null)}
        action={confirmAction ?? "accept"}
        clientName={appointment.clientName}
        onConfirm={() => {
          if (confirmAction === "accept") {
            onAccept?.(appointment.id);
          } else {
            onDecline?.(appointment.id);
          }
          setConfirmAction(null);
          onOpenChange(false);
        }}
      />

      <AppointmentRescheduleDialog
        open={rescheduleOpen}
        onOpenChange={setRescheduleOpen}
        amSlots={amSlots}
        pmSlots={pmSlots}
        currentDate={appointment.date}
        currentTimeStart={appointment.timeStart}
        currentTimeEnd={appointment.timeEnd}
        onDateChange={onDateChange}
        schedule={schedule}
        isLoadingSlots={isLoadingSlots}
        onReschedule={(date, slot, note) => {
          onReschedule?.(appointment.id, date, slot, note);
          setRescheduleOpen(false);
        }}
      />
    </>
  );
}
