"use client";
import { useEffect, useState, useCallback } from "react";
import Link from "next/link";
import {
  Plus, X, Calendar, Clock, CheckCircle, XCircle, AlertTriangle,
  Phone, Send, Undo2, Search, ChevronDown, User, Stethoscope,
  CalendarDays, CalendarCheck, CalendarX, Filter, Trash2, Zap,
} from "lucide-react";
import TimeSlotPicker from "@/components/TimeSlotPicker";

interface Lead { id: string; name: string; phone: string; }
interface Treatment { id: string; name: string; duration: number; price: number | null; }
interface ScheduledReminder { id: string; scheduledFor: string; status: string; template: { trigger: string } | null; }
interface Appointment {
  id: string; dateTime: string; status: string; notes: string | null;
  lead: Lead; treatment: Treatment; scheduledReminders: ScheduledReminder[];
}

const STATUSES: Record<string, { badge: string; label: string; color: string }> = {
  scheduled:   { badge: "badge-scheduled",  label: "Scheduled",   color: "#f59e0b" },
  confirmed:   { badge: "badge-confirmed",  label: "Confirmed",   color: "#10b981" },
  arrived:     { badge: "badge-arrived",     label: "Arrived",     color: "#059669" },
  in_progress: { badge: "badge-booked",     label: "In Progress", color: "#6366f1" },
  completed:   { badge: "badge-completed",  label: "Completed",   color: "#047857" },
  no_show:     { badge: "badge-no-show",    label: "No Show",     color: "#ef4444" },
  cancelled:   { badge: "badge-cancelled",  label: "Cancelled",   color: "#94a3b8" },
  rescheduled: { badge: "badge-cancelled",  label: "Rescheduled", color: "#8b5cf6" },
};

const STATUS_PILLS = [
  { key: "all",         label: "All",         color: "#6366f1" },
  { key: "scheduled",   label: "Scheduled",   color: "#f59e0b" },
  { key: "confirmed",   label: "Confirmed",   color: "#10b981" },
  { key: "rescheduled", label: "Rescheduled", color: "#8b5cf6" },
  { key: "cancelled",   label: "Cancelled",   color: "#94a3b8" },
  { key: "no_show",     label: "No Show",     color: "#ef4444" },
];

const STATUS_EMOJI: Record<string, string> = {
  scheduled: "🟡", confirmed: "✅", rescheduled: "🔄", cancelled: "❌", no_show: "🚫",
};

const EMPTY_MESSAGES: Record<string, { title: string; desc: string }> = {
  all:         { title: "No appointments",        desc: "Book your first appointment to start sending automated reminders" },
  scheduled:   { title: "No scheduled visits",    desc: "All appointments have been confirmed or processed" },
  confirmed:   { title: "No confirmed visits",    desc: "Confirmed appointments will appear here" },
  rescheduled: { title: "No rescheduled visits",  desc: "Rescheduled appointments will appear here" },
  cancelled:   { title: "No cancellations",       desc: "Great news — no cancelled appointments!" },
  no_show:     { title: "No no-shows",            desc: "All patients showed up — excellent!" },
};

const ACTIONS: Record<string, { label: string; icon: string; next: string; primary: boolean }[]> = {
  scheduled:   [{ label: "Confirm", icon: "✅", next: "confirmed", primary: true }, { label: "Cancel", icon: "✕", next: "cancelled", primary: false }],
  confirmed:   [{ label: "Arrived", icon: "🏥", next: "arrived", primary: true }, { label: "No Show", icon: "✕", next: "no_show", primary: false }],
  arrived:     [{ label: "Start", icon: "▶", next: "in_progress", primary: true }],
  in_progress: [{ label: "Complete", icon: "🎉", next: "completed", primary: true }],
};

const TRIGGER_EMOJI: Record<string, string> = {
  booking_confirmed: "📋", "3_days_before": "📅", "1_day_before": "⏰", "2_hours_before": "🕐",
  "30_min_before": "🔔", "1_hour_after_noshow": "😟", "1_day_after_noshow": "📞",
  post_treatment_same_day: "💊", post_treatment_3_days: "💬",
};

export default function AppointmentsPage() {
  const [appointments, setAppointments] = useState<Appointment[]>([]);
  const [leads, setLeads] = useState<Lead[]>([]);
  const [treatments, setTreatments] = useState<Treatment[]>([]);
  const [loading, setLoading] = useState(true);
  const [workStart, setWorkStart] = useState(8);
  const [workEnd, setWorkEnd] = useState(22);
  const [showAdd, setShowAdd] = useState(false);
  const [form, setForm] = useState({ leadId: "", treatmentId: "", dateTime: "", notes: "" });
  const [saving, setSaving] = useState(false);
  const [tab, setTab] = useState("upcoming");
  const [statusFilter, setStatusFilter] = useState("all");
  const [search, setSearch] = useState("");
  const [expandedId, setExpandedId] = useState<string | null>(null);
  const [undo, setUndo] = useState<{ id: string; prev: string } | null>(null);
  const [effects, setEffects] = useState<Record<string, string>>({});
  const [toast, setToast] = useState<{ msg: string; type: "success" | "error" } | null>(null);

  const load = useCallback(() => {
    const safe = (r: Response) => r.ok ? r.json() : Promise.resolve({});
    Promise.all([
      fetch("/api/appointments").then(safe),
      fetch("/api/leads").then(safe),
      fetch("/api/treatments").then(safe),
      fetch("/api/clinic").then(safe),
    ]).then(([a, l, t, c]) => {
      if (Array.isArray(a)) setAppointments(a);
      if (Array.isArray(l)) setLeads(l);
      if (Array.isArray(t)) setTreatments(t);
      if (c?.quietHoursEnd !== undefined) setWorkStart(c.quietHoursEnd);
      if (c?.quietHoursStart !== undefined) setWorkEnd(c.quietHoursStart);
    }).finally(() => setLoading(false));
  }, []);
  useEffect(() => {
    load();
    const interval = setInterval(load, 15_000);
    return () => clearInterval(interval);
  }, [load]);

  const showToast = (msg: string, type: "success" | "error" = "success") => {
    setToast({ msg, type }); setTimeout(() => setToast(null), 3500);
  };

  const handleAdd = async (e: React.FormEvent) => {
    e.preventDefault(); setSaving(true);
    try {
      if (form.leadId) {
        const res = await fetch("/api/appointments", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(form) });
        if (res.ok) {
          setForm({ leadId: "", treatmentId: "", dateTime: "", notes: "" }); setShowAdd(false);
          showToast("Appointment booked! Reminders scheduled.");
          load();
        } else {
          const err = await res.json().catch(() => ({}));
          showToast(err.error || "Failed to book", "error");
        }
      } else {
        showToast("Please select a patient", "error");
      }
    } catch { showToast("Network error", "error"); }
    setSaving(false);
  };

  const [showQuickBook, setShowQuickBook] = useState(false);
  const [qbForm, setQbForm] = useState({ name: "", phone: "", treatmentId: "", dateTime: "", notes: "" });
  const [qbSaving, setQbSaving] = useState(false);

  const handleQuickBook = async (e: React.FormEvent) => {
    e.preventDefault(); setQbSaving(true);
    try {
      const res = await fetch("/api/appointments/quick-book", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(qbForm),
      });
      if (res.ok) {
        setQbForm({ name: "", phone: "", treatmentId: "", dateTime: "", notes: "" });
        setShowQuickBook(false);
        showToast("⚡ Quick booked! Lead created + reminders scheduled.");
        load();
      } else {
        const err = await res.json().catch(() => ({}));
        showToast(err.error || "Failed to book", "error");
      }
    } catch { showToast("Network error", "error"); }
    setQbSaving(false);
  };

  const updateStatus = async (id: string, status: string, prev: string) => {
    if (status === "confirmed" || status === "completed") {
      setEffects(p => ({ ...p, [id]: "status-glow-green" }));
    } else if (status === "no_show" || status === "cancelled") {
      setEffects(p => ({ ...p, [id]: "status-shake" }));
    }
    setTimeout(() => setEffects(p => { const n = { ...p }; delete n[id]; return n; }), 1500);
    await fetch(`/api/appointments/${id}/status`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ status }) });
    setUndo({ id, prev }); setTimeout(() => setUndo(null), 5000);
    load();
  };

  const handleUndo = async () => {
    if (!undo) return;
    await fetch(`/api/appointments/${undo.id}/status`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ status: undo.prev }) });
    setUndo(null); load();
  };

  const handleDelete = async (apt: Appointment) => {
    if (!confirm(`Delete appointment for ${apt.lead.name}?`)) return;
    const res = await fetch(`/api/appointments/${apt.id}`, { method: "DELETE" });
    if (res.ok) { showToast("Appointment deleted"); load(); }
    else showToast("Failed to delete", "error");
  };

  const now = new Date();
  const today = new Date(); today.setHours(0, 0, 0, 0);
  const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1);

  // Time tab filter
  const timeFiltered = appointments.filter(a => {
    const dt = new Date(a.dateTime);
    if (tab === "today") return dt >= today && dt < tomorrow;
    if (tab === "upcoming") return dt >= now && !["cancelled", "completed", "no_show", "rescheduled"].includes(a.status);
    if (tab === "past") return dt < now || ["completed", "no_show", "cancelled", "rescheduled"].includes(a.status);
    return true;
  });

  // Status filter (AND with time)
  const statusFiltered = statusFilter === "all" ? timeFiltered : timeFiltered.filter(a => a.status === statusFilter);

  // Search filter
  const filtered = statusFiltered.filter(a => !search || a.lead.name.toLowerCase().includes(search.toLowerCase()) || a.lead.phone.includes(search));

  // Sort: upcoming = nearest first, past = oldest first
  const sorted = [...filtered].sort((a, b) => {
    const da = new Date(a.dateTime).getTime();
    const db = new Date(b.dateTime).getTime();
    return tab === "past" ? db - da : da - db;
  });

  // Status counts (within current time tab)
  const statusCounts: Record<string, number> = { all: timeFiltered.length };
  for (const pill of STATUS_PILLS) {
    if (pill.key !== "all") {
      statusCounts[pill.key] = timeFiltered.filter(a => a.status === pill.key).length;
    }
  }

  const todayCount = appointments.filter(a => { const dt = new Date(a.dateTime); return dt >= today && dt < tomorrow; }).length;
  const upcomingCount = appointments.filter(a => new Date(a.dateTime) >= now && !["cancelled", "completed", "no_show", "rescheduled"].includes(a.status)).length;
  const confirmedCount = appointments.filter(a => a.status === "confirmed").length;
  const cancelledNoShowCount = appointments.filter(a => ["cancelled", "no_show"].includes(a.status)).length;

  const handleStatClick = (tabKey: string, status?: string) => {
    setTab(tabKey);
    setStatusFilter(status || "all");
  };

  return (
    <>
      {/* ── Toast ── */}
      {toast && (
        <div className={`clinera-toast fixed top-5 right-5 z-[9999] px-5 py-3 rounded-xl shadow-2xl flex items-center gap-3 text-sm font-semibold text-white ${
          toast.type === "success" ? "bg-gradient-to-r from-emerald-600 to-emerald-500" : "bg-gradient-to-r from-red-600 to-red-500"
        }`} style={{ animation: "toast-in 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both" }}>
          {toast.type === "success" ? <CheckCircle size={16} /> : <XCircle size={16} />}
          {toast.msg}
        </div>
      )}

      {/* ── Undo Toast ── */}
      {undo && (
        <div className="fixed bottom-5 left-1/2 -translate-x-1/2 z-[9999] bg-gray-900 text-white px-5 py-3 rounded-xl shadow-2xl flex items-center gap-3 animate-slide-up text-sm">
          <CheckCircle size={14} className="text-emerald-400" /> Status updated
          <button onClick={handleUndo} className="flex items-center gap-1 px-3 py-1 bg-white/10 hover:bg-white/20 rounded-lg text-xs font-semibold transition-colors">
            <Undo2 size={12} /> Undo
          </button>
        </div>
      )}

      {/* ── Add Modal ── */}
      {showAdd && (
        <div className="modal-overlay" onClick={() => setShowAdd(false)}>
          <div className="card p-6 w-full max-w-md animate-scale-in" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-5">
              <div className="flex items-center gap-2.5">
                <div className="w-8 h-8 rounded-lg bg-primary-50 flex items-center justify-center">
                  <CalendarCheck size={16} className="text-primary-600" />
                </div>
                <h2 className="text-base font-bold">Book Appointment</h2>
              </div>
              <button onClick={() => setShowAdd(false)} className="p-1.5 hover:bg-gray-100 rounded-lg text-gray-400"><X size={18} /></button>
            </div>
            {treatments.length === 0 ? (
              <div className="text-center py-10">
                <div className="w-12 h-12 bg-amber-50 rounded-2xl flex items-center justify-center mx-auto mb-3"><AlertTriangle size={22} className="text-amber-400" /></div>
                <p className="font-semibold text-sm mb-1">Add treatments first</p>
                <p className="text-xs text-gray-400 mb-4">You need at least one treatment to book</p>
                <Link href="/treatments" className="btn-primary btn-sm">Go to Treatments →</Link>
              </div>
            ) : leads.length === 0 ? (
              <div className="text-center py-10">
                <div className="w-12 h-12 bg-amber-50 rounded-2xl flex items-center justify-center mx-auto mb-3"><AlertTriangle size={22} className="text-amber-400" /></div>
                <p className="font-semibold text-sm mb-1">Add a lead first</p>
                <p className="text-xs text-gray-400 mb-4">You need at least one patient to book</p>
                <Link href="/leads" className="btn-primary btn-sm">Go to Leads →</Link>
              </div>
            ) : (
              <form onSubmit={handleAdd} className="space-y-4">
                <div>
                  <label className="block text-xs font-semibold text-gray-500 mb-1.5">Patient *</label>
                  <select value={form.leadId} onChange={e => setForm(p => ({ ...p, leadId: e.target.value }))} required className="input">
                    <option value="">Select patient...</option>
                    {leads.map(l => <option key={l.id} value={l.id}>{l.name} — {l.phone}</option>)}
                  </select>
                </div>
                <div>
                  <label className="block text-xs font-semibold text-gray-500 mb-1.5">Treatment *</label>
                  <select value={form.treatmentId} onChange={e => setForm(p => ({ ...p, treatmentId: e.target.value }))} required className="input">
                    <option value="">Select treatment...</option>
                    {treatments.map(t => <option key={t.id} value={t.id}>{t.name} ({t.duration}min{t.price ? ` · $${t.price}` : ""})</option>)}
                  </select>
                </div>
                <TimeSlotPicker
                  value={form.dateTime}
                  onChange={(v) => setForm(p => ({ ...p, dateTime: v }))}
                  workStart={workStart}
                  workEnd={workEnd}
                  interval={30}
                />
                <div>
                  <label className="block text-xs font-semibold text-gray-500 mb-1.5">Notes</label>
                  <textarea value={form.notes} onChange={e => setForm(p => ({ ...p, notes: e.target.value }))} placeholder="Optional..." className="input" rows={2} />
                </div>
                <div className="bg-primary-50/50 rounded-xl p-3 border border-primary-100">
                  <p className="text-[11px] font-semibold text-primary-700 mb-2">📱 Auto-reminders will fire:</p>
                  <div className="flex flex-wrap gap-1.5">
                    {["📋 Booking", "📅 3d before", "⏰ 1d before", "🕐 2h before", "🔔 30min"].map((r, i) => (
                      <span key={i} className="px-2 py-0.5 bg-white rounded-md text-[10px] font-medium text-primary-600 border border-primary-100">{r}</span>
                    ))}
                  </div>
                </div>
                <div className="flex gap-2 pt-1">
                  <button type="button" onClick={() => setShowAdd(false)} className="btn-secondary flex-1">Cancel</button>
                  <button type="submit" disabled={saving} className="btn-primary flex-1">{saving ? "Booking..." : "📅 Book Appointment"}</button>
                </div>
              </form>
            )}
          </div>
        </div>
      )}

      {/* ── Quick Book Modal ── */}
      {showQuickBook && (
        <div className="modal-overlay" onClick={() => setShowQuickBook(false)}>
          <div className="card p-6 w-full max-w-md animate-scale-in" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-5">
              <div className="flex items-center gap-2.5">
                <div className="w-8 h-8 rounded-lg bg-amber-50 flex items-center justify-center">
                  <Zap size={16} className="text-amber-600" />
                </div>
                <div>
                  <h2 className="text-base font-bold">Quick Book</h2>
                  <p className="text-[10px] text-gray-400">Name + Phone + Treatment + Time = Done</p>
                </div>
              </div>
              <button onClick={() => setShowQuickBook(false)} className="p-1.5 hover:bg-gray-100 rounded-lg text-gray-400"><X size={18} /></button>
            </div>
            {treatments.length === 0 ? (
              <div className="text-center py-10">
                <div className="w-12 h-12 bg-amber-50 rounded-2xl flex items-center justify-center mx-auto mb-3"><AlertTriangle size={22} className="text-amber-400" /></div>
                <p className="font-semibold text-sm mb-1">Add treatments first</p>
                <p className="text-xs text-gray-400 mb-4">You need at least one treatment</p>
              </div>
            ) : (
              <form onSubmit={handleQuickBook} className="space-y-4">
                <div className="grid grid-cols-2 gap-3">
                  <div>
                    <label className="block text-xs font-semibold text-gray-500 mb-1.5">Patient Name *</label>
                    <input type="text" value={qbForm.name} onChange={e => setQbForm(p => ({ ...p, name: e.target.value }))} placeholder="Patient name" required className="input" autoFocus />
                  </div>
                  <div>
                    <label className="block text-xs font-semibold text-gray-500 mb-1.5">WhatsApp # *</label>
                    <input type="tel" value={qbForm.phone} onChange={e => setQbForm(p => ({ ...p, phone: e.target.value }))} placeholder="+966 5X XXX XXXX" required className="input" />
                  </div>
                </div>
                <div>
                  <label className="block text-xs font-semibold text-gray-500 mb-1.5">Treatment *</label>
                  <select value={qbForm.treatmentId} onChange={e => setQbForm(p => ({ ...p, treatmentId: e.target.value }))} required className="input">
                    <option value="">Select treatment...</option>
                    {treatments.map(t => <option key={t.id} value={t.id}>{t.name} ({t.duration}min{t.price ? ` · $${t.price}` : ""})</option>)}
                  </select>
                </div>
                <TimeSlotPicker
                  value={qbForm.dateTime}
                  onChange={(v) => setQbForm(p => ({ ...p, dateTime: v }))}
                  workStart={workStart}
                  workEnd={workEnd}
                  interval={30}
                />
                <div className="bg-amber-50/50 rounded-xl p-3 border border-amber-100">
                  <p className="text-[11px] font-semibold text-amber-700">⚡ What happens:</p>
                  <p className="text-[10px] text-amber-600 mt-1">Lead auto-created (or matched if phone exists) → Appointment booked → WhatsApp confirmation sent → Full reminder sequence activated</p>
                </div>
                <div className="flex gap-2 pt-1">
                  <button type="button" onClick={() => setShowQuickBook(false)} className="btn-secondary flex-1">Cancel</button>
                  <button type="submit" disabled={qbSaving} className="btn-primary flex-1">{qbSaving ? "Booking..." : "⚡ Quick Book"}</button>
                </div>
              </form>
            )}
          </div>
        </div>
      )}

      {/* ═══════════════════════════════════════════ */}
      {/*                 PAGE CONTENT                */}
      {/* ═══════════════════════════════════════════ */}
      <div className="space-y-6 animate-fade-in">

        {/* ── Header ── */}
        <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3">
          <div className="flex items-center gap-3">
            <div className="w-10 sm:w-11 h-10 sm:h-11 rounded-xl bg-gradient-to-br from-amber-400 to-orange-500 flex items-center justify-center shadow-lg shadow-amber-500/20">
              <Calendar size={20} className="text-white" />
            </div>
            <div>
              <h1 className="text-xl sm:text-2xl font-bold tracking-tight text-dark">Appointments</h1>
              <p className="text-xs sm:text-sm text-muted flex items-center gap-1.5">
                {appointments.length} total · {todayCount} today
                <span className="inline-flex items-center gap-1 text-emerald-500 font-semibold">
                  <span className="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse inline-block" />
                  live
                </span>
              </p>
            </div>
          </div>
          <div className="flex gap-2">
            <button onClick={() => setShowQuickBook(true)} className="btn-secondary btn-sm"><Zap size={15} /> <span className="hidden sm:inline">Quick </span>Book</button>
            <button onClick={() => setShowAdd(true)} className="btn-primary btn-sm"><Plus size={15} /> <span className="hidden sm:inline">Book Appointment</span><span className="inline sm:hidden">New</span></button>
          </div>
        </div>

        {/* ── Stats Bar ── */}
        <div className="grid grid-cols-2 sm:grid-cols-4 gap-3 sm:gap-4">
          {[
            { label: "Today", value: todayCount, icon: CalendarDays, color: "#f59e0b", tabKey: "today" },
            { label: "Upcoming", value: upcomingCount, icon: Calendar, color: "#6366f1", tabKey: "upcoming" },
            { label: "Confirmed", value: confirmedCount, icon: CalendarCheck, color: "#10b981", tabKey: "all", status: "confirmed" },
            { label: "Cancelled", value: cancelledNoShowCount, icon: CalendarX, color: "#94a3b8", tabKey: "all", status: "cancelled" },
          ].map((s, i) => (
            <button key={i} onClick={() => handleStatClick(s.tabKey, s.status)}
              className="text-left border rounded-2xl p-4 flex items-center gap-3 transition-all hover:scale-[1.02] hover:shadow-md cursor-pointer"
              style={{ backgroundColor: s.color + "08", borderColor: s.color + "20" }}>
              <div className="w-10 h-10 rounded-xl flex items-center justify-center" style={{ backgroundColor: s.color + "15" }}>
                <s.icon size={18} style={{ color: s.color }} />
              </div>
              <div>
                <p className="text-2xl font-bold" style={{ color: s.color }}>{s.value}</p>
                <p className="text-[11px] text-muted font-medium">{s.label}</p>
              </div>
            </button>
          ))}
        </div>

        {/* ── Row 1: Time Tabs ── */}
        <div className="flex flex-col gap-3">
          <div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-3 sm:gap-4">
            <div className="flex gap-1 bg-gray-100/80 rounded-xl p-1 overflow-x-auto scrollbar-hide">
              {[
                { key: "today", label: "Today", count: todayCount },
                { key: "upcoming", label: "Upcoming", count: upcomingCount },
                { key: "all", label: "All", count: appointments.length },
                { key: "past", label: "Past" },
              ].map(t => (
                <button key={t.key} onClick={() => { setTab(t.key); setStatusFilter("all"); }}
                  className={`px-3 sm:px-4 py-2 rounded-lg text-xs font-semibold transition-all whitespace-nowrap ${
                    tab === t.key
                      ? "bg-white text-dark shadow-sm"
                      : "text-gray-400 hover:text-gray-600"
                  }`}>
                  {t.label}
                  {t.count !== undefined && t.count > 0 && <span className="ml-1 text-[10px] opacity-50">{t.count}</span>}
                </button>
              ))}
            </div>
            <div className="relative flex-1 sm:max-w-xs">
              <Search size={14} className="absolute left-3.5 top-1/2 -translate-y-1/2 text-gray-300" />
              <input type="text" value={search} onChange={e => setSearch(e.target.value)}
                placeholder="Search patient or phone..." className="input pl-10 py-2.5 text-sm" />
              {search && (
                <button onClick={() => setSearch("")} className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-300 hover:text-gray-500">
                  <X size={14} />
                </button>
              )}
            </div>
          </div>

          {/* ── Row 2: Status Filter Pills ── */}
          <div className="flex gap-2 overflow-x-auto scrollbar-hide pb-1">
            {STATUS_PILLS.map(pill => {
              const active = statusFilter === pill.key;
              const count = statusCounts[pill.key] || 0;
              return (
                <button key={pill.key} onClick={() => setStatusFilter(pill.key)}
                  className="flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-semibold whitespace-nowrap border transition-all duration-200 hover:scale-[1.03] active:scale-95 shrink-0"
                  style={active ? {
                    backgroundColor: pill.color,
                    color: "#fff",
                    borderColor: pill.color,
                    boxShadow: `0 2px 8px ${pill.color}40`,
                  } : {
                    backgroundColor: "transparent",
                    color: "#9ca3af",
                    borderColor: "#e5e7eb",
                  }}>
                  {pill.key !== "all" && (
                    <span className="w-2 h-2 rounded-full shrink-0" style={{ backgroundColor: active ? "#fff" : pill.color }} />
                  )}
                  {pill.label}
                  <span className="text-[10px] font-bold ml-0.5 px-1.5 py-0.5 rounded-full"
                    style={active ? {
                      backgroundColor: "rgba(255,255,255,0.25)",
                      color: "#fff",
                    } : {
                      backgroundColor: "#f3f4f6",
                      color: "#9ca3af",
                    }}>
                    {count}
                  </span>
                </button>
              );
            })}
          </div>
        </div>

        {/* ── Appointment List ── */}
        {loading ? (
          <div className="flex flex-col items-center justify-center py-24 gap-3">
            <div className="w-8 h-8 border-[2.5px] border-primary-100 border-t-primary-500 rounded-full animate-spin" />
            <p className="text-xs text-gray-400">Loading appointments...</p>
          </div>
        ) : sorted.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-20 text-center">
            <div className="w-16 h-16 bg-primary-50 rounded-2xl flex items-center justify-center mb-4 animate-float">
              <Calendar size={28} className="text-primary-300" />
            </div>
            <h3 className="text-lg font-bold text-dark mb-1">
              {search ? "No results" : (EMPTY_MESSAGES[statusFilter]?.title || "No appointments")}
            </h3>
            <p className="text-sm text-gray-400 mb-6 max-w-xs">
              {search ? "No results for your search" : (EMPTY_MESSAGES[statusFilter]?.desc || "Book your first appointment to start sending automated reminders")}
            </p>
            {!search && statusFilter === "all" && (
              <button onClick={() => setShowAdd(true)} className="btn-primary">
                <Plus size={15} /> Book First Appointment
              </button>
            )}
          </div>
        ) : (
          <div className="space-y-2">
            {sorted.map((apt, idx) => {
              const dt = new Date(apt.dateTime);
              const st = STATUSES[apt.status] || STATUSES.scheduled;
              const actions = ACTIONS[apt.status] || [];
              const open = expandedId === apt.id;
              const sentCount = apt.scheduledReminders.filter(r => r.status === "sent").length;
              const totalCount = apt.scheduledReminders.length;
              const isPast = dt < now && !["arrived", "in_progress"].includes(apt.status);
              const effect = effects[apt.id] || "";
              const isTerminal = ["completed", "cancelled", "no_show", "rescheduled"].includes(apt.status);

              const weekday = dt.toLocaleDateString("en-US", { weekday: "short" });
              const day = dt.getDate();
              const time = dt.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit", hour12: true });

              return (
                <div key={apt.id}
                  className={`apt-row-enter card card-flat overflow-hidden relative group hover:shadow-lg transition-shadow duration-200 ${isPast && apt.status !== "completed" ? "opacity-50" : ""} ${effect}`}
                  style={{ animationDelay: `${idx * 40}ms` }}>

                  <div className="flex items-stretch">
                    {/* Left status strip */}
                    <div className="w-1 self-stretch rounded-l-2xl shrink-0" style={{ backgroundColor: st.color }} />

                    <div className="flex flex-wrap sm:flex-nowrap items-center gap-3 sm:gap-4 px-4 sm:px-5 py-3 sm:py-4 flex-1 min-w-0">
                      {/* Date block */}
                      <div className="text-center w-14 shrink-0 py-3 px-2 rounded-xl" style={{ backgroundColor: st.color + "18" }}>
                        <p className="text-[9px] font-bold uppercase tracking-wide" style={{ color: st.color }}>{weekday}</p>
                        <p className="text-2xl font-black text-dark leading-none">{day}</p>
                        <p className="text-[10px] font-semibold text-gray-500 mt-1">{time}</p>
                      </div>

                      {/* Content */}
                      <div className="flex-1 min-w-0 py-1">
                        <div className="flex items-center gap-2 mb-1">
                          <span className="font-bold text-[15px] text-dark truncate">{apt.lead.name}</span>
                          <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md text-[11px] font-semibold border"
                            style={{ backgroundColor: st.color + "18", color: st.color, borderColor: st.color + "30" }}>
                            {st.label}
                          </span>
                          {apt.status === "confirmed" && <span className="text-xs">✅</span>}
                          {apt.status === "rescheduled" && <span className="text-xs">🔄</span>}
                          {apt.status === "cancelled" && <span className="text-xs">❌</span>}
                          {apt.status === "no_show" && <span className="text-xs">🚫</span>}
                        </div>
                        <div className="flex flex-wrap items-center gap-x-3 gap-y-1 text-[12px] text-gray-400">
                          <span className="flex items-center gap-1"><Stethoscope size={11} /> {apt.treatment.name}</span>
                          <span className="flex items-center gap-1"><Phone size={11} /> {apt.lead.phone}</span>
                          {totalCount > 0 && (
                            <span className="flex items-center gap-1 text-primary-400">
                              <Send size={11} /> {sentCount}/{totalCount} reminders
                            </span>
                          )}
                        </div>
                      </div>

                      {/* Actions */}
                      <div className="flex items-center gap-1.5 sm:gap-2 shrink-0 ml-auto sm:ml-0">
                        {actions.map(a => (
                          <button key={a.next} onClick={() => updateStatus(apt.id, a.next, apt.status)}
                            className={`px-2.5 sm:px-3 py-1.5 sm:py-2 text-[11px] sm:text-[12px] font-semibold rounded-lg sm:rounded-xl transition-all hover:scale-105 active:scale-95 ${
                              a.primary
                                ? "bg-emerald-600 hover:bg-emerald-700 text-white shadow-sm shadow-emerald-500/20"
                                : "bg-gray-100 hover:bg-gray-200 text-gray-600"
                            }`}>
                            {a.icon} <span className="hidden sm:inline">{a.label}</span>
                          </button>
                        ))}
                        {isTerminal && (
                          <button onClick={() => handleDelete(apt)}
                            className="p-2 text-gray-300 hover:text-red-500 rounded-lg hover:bg-red-50 transition-all opacity-0 group-hover:opacity-100"
                            title="Delete appointment">
                            <Trash2 size={14} />
                          </button>
                        )}
                        {totalCount > 0 && (
                          <button onClick={() => setExpandedId(open ? null : apt.id)}
                            className="p-2 text-gray-300 hover:text-gray-500 rounded-lg hover:bg-gray-50 transition-all">
                            <ChevronDown size={16} className={`transition-transform duration-300 ${open ? "rotate-180" : ""}`} />
                          </button>
                        )}
                      </div>
                    </div>
                  </div>

                  {/* Reminder timeline */}
                  {open && (
                    <div className="border-t border-gray-100 px-6 py-4 bg-gray-50/50 animate-fade-in">
                      <p className="text-[11px] font-bold text-gray-400 uppercase tracking-wider mb-3">Reminder Journey</p>
                      <div className="space-y-2">
                        {apt.scheduledReminders.map((r, ri) => {
                          const trigger = r.template?.trigger || "unknown";
                          return (
                            <div key={r.id} className="flex items-center gap-3 text-xs"
                              style={{ animation: `fade-in 0.3s ease both`, animationDelay: `${ri * 50}ms` }}>
                              <span className="text-base w-6 text-center">{TRIGGER_EMOJI[trigger] || "📨"}</span>
                              <span className={`flex-1 ${r.status === "skipped" ? "text-gray-300 line-through" : "text-gray-600"}`}>
                                {trigger.replace(/_/g, " ")}
                              </span>
                              <span className="text-[11px] text-gray-400 tabular-nums">
                                {new Date(r.scheduledFor).toLocaleString("en-US", { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" })}
                              </span>
                              <span className={`text-[11px] font-semibold w-14 text-right ${
                                r.status === "sent" ? "text-emerald-500" : r.status === "failed" ? "text-red-500" : r.status === "skipped" ? "text-gray-300" : "text-amber-500"
                              }`}>
                                {r.status}
                              </span>
                            </div>
                          );
                        })}
                      </div>
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        )}
      </div>
    </>
  );
}
