"use client";
import { useEffect, useState, useCallback, useMemo, useRef } from "react";
import {
  ChevronLeft, ChevronRight, Plus, X, Phone, Stethoscope, Clock,
} from "lucide-react";

interface Lead { id: string; name: string; phone: string; }
interface Treatment { id: string; name: string; duration: number; price: number | null; }
interface Appointment {
  id: string; dateTime: string; status: string; notes: string | null;
  lead: Lead; treatment: Treatment;
}

const STATUS_COLORS: Record<string, string> = {
  scheduled: "#f59e0b", confirmed: "#10b981", rescheduled: "#8b5cf6",
  cancelled: "#94a3b8", no_show: "#ef4444", arrived: "#059669",
  completed: "#047857", in_progress: "#6366f1", booked: "#3b82f6",
};

const STATUS_LABELS: Record<string, string> = {
  scheduled: "Scheduled", confirmed: "Confirmed", rescheduled: "Rescheduled",
  cancelled: "Cancelled", no_show: "No Show", arrived: "Arrived",
  completed: "Completed", in_progress: "In Progress", booked: "Booked",
};

const DAY_START = 8; // 08:00
const DAY_END = 20;  // 20:00
const TOTAL_MINUTES = (DAY_END - DAY_START) * 60; // 720

function getMonday(d: Date): Date {
  const date = new Date(d);
  const day = date.getDay();
  const diff = date.getDate() - day + (day === 0 ? -6 : 1);
  date.setDate(diff);
  date.setHours(0, 0, 0, 0);
  return date;
}

function formatDateRange(monday: Date): string {
  const sunday = new Date(monday);
  sunday.setDate(sunday.getDate() + 6);
  const opts: Intl.DateTimeFormatOptions = { month: "short", day: "numeric" };
  const start = monday.toLocaleDateString("en-US", opts);
  const end = sunday.toLocaleDateString("en-US", { ...opts, year: "numeric" });
  return `${start} – ${end}`;
}

function isSameDay(a: Date, b: Date): boolean {
  return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
}

function minutesSinceDayStart(d: Date): number {
  return (d.getHours() - DAY_START) * 60 + d.getMinutes();
}

export default function CalendarPage() {
  const [appointments, setAppointments] = useState<Appointment[]>([]);
  const [treatments, setTreatments] = useState<Treatment[]>([]);
  const [loading, setLoading] = useState(true);
  const [view, setView] = useState<"week" | "day">("week");
  const [currentDate, setCurrentDate] = useState(() => new Date());
  const [selectedApt, setSelectedApt] = useState<Appointment | null>(null);
  const [popoverPos, setPopoverPos] = useState<{ x: number; y: number } | null>(null);
  const [showQuickBook, setShowQuickBook] = useState(false);
  const [quickBookSlot, setQuickBookSlot] = useState<{ date: Date; time: string } | null>(null);
  const [qbForm, setQbForm] = useState({ name: "", phone: "", treatmentId: "" });
  const [qbSaving, setQbSaving] = useState(false);
  const [updatingStatus, setUpdatingStatus] = useState(false);
  const gridRef = useRef<HTMLDivElement>(null);
  const now = new Date();

  // Responsive: default to day view on mobile
  useEffect(() => {
    if (window.innerWidth < 768) setView("day");
  }, []);

  const load = useCallback(() => {
    const safe = (r: Response) => r.ok ? r.json() : Promise.resolve([]);
    Promise.all([
      fetch("/api/appointments").then(safe),
      fetch("/api/treatments").then(safe),
    ]).then(([a, t]) => {
      if (Array.isArray(a)) setAppointments(a);
      if (Array.isArray(t)) setTreatments(t);
    }).finally(() => setLoading(false));
  }, []);

  useEffect(() => { load(); }, [load]);

  const monday = useMemo(() => getMonday(currentDate), [currentDate]);

  const weekDays = useMemo(() => {
    return Array.from({ length: 7 }, (_, i) => {
      const d = new Date(monday);
      d.setDate(d.getDate() + i);
      return d;
    });
  }, [monday]);

  const visibleDays = useMemo(() => view === "week" ? weekDays : [currentDate], [view, weekDays, currentDate]);

  const timeSlots = useMemo(() => {
    const slots: string[] = [];
    for (let h = DAY_START; h < DAY_END; h++) {
      slots.push(`${h.toString().padStart(2, "0")}:00`);
      slots.push(`${h.toString().padStart(2, "0")}:30`);
    }
    return slots;
  }, []);

  const appointmentsByDay = useMemo(() => {
    const map = new Map<string, Appointment[]>();
    for (const apt of appointments) {
      const dt = new Date(apt.dateTime);
      const key = `${dt.getFullYear()}-${dt.getMonth()}-${dt.getDate()}`;
      if (!map.has(key)) map.set(key, []);
      map.get(key)!.push(apt);
    }
    return map;
  }, [appointments]);

  const getAptsForDay = useCallback((day: Date): Appointment[] => {
    const key = `${day.getFullYear()}-${day.getMonth()}-${day.getDate()}`;
    return appointmentsByDay.get(key) || [];
  }, [appointmentsByDay]);

  const navigate = useCallback((dir: number) => {
    setCurrentDate(prev => {
      const d = new Date(prev);
      d.setDate(d.getDate() + (view === "week" ? dir * 7 : dir));
      return d;
    });
    setSelectedApt(null);
  }, [view]);

  const goToday = useCallback(() => {
    setCurrentDate(new Date());
    setSelectedApt(null);
  }, []);

  const handleAptClick = useCallback((apt: Appointment, e: React.MouseEvent) => {
    e.stopPropagation();
    const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
    setPopoverPos({ x: rect.left + rect.width / 2, y: rect.bottom + 4 });
    setSelectedApt(apt);
  }, []);

  const handleSlotClick = useCallback((day: Date, time: string) => {
    const [h, m] = time.split(":").map(Number);
    const slotDate = new Date(day);
    slotDate.setHours(h, m, 0, 0);
    if (slotDate < new Date()) return;
    setQuickBookSlot({ date: slotDate, time });
    setQbForm({ name: "", phone: "", treatmentId: "" });
    setShowQuickBook(true);
  }, []);

  const handleQuickBook = useCallback(async (e: React.FormEvent) => {
    e.preventDefault();
    if (!quickBookSlot) return;
    setQbSaving(true);
    try {
      const res = await fetch("/api/appointments/quick-book", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          name: qbForm.name,
          phone: qbForm.phone,
          treatmentId: qbForm.treatmentId,
          dateTime: quickBookSlot.date.toISOString(),
        }),
      });
      if (res.ok) {
        setShowQuickBook(false);
        load();
      }
    } catch {}
    setQbSaving(false);
  }, [qbForm, quickBookSlot, load]);

  const updateStatus = useCallback(async (id: string, status: string) => {
    setUpdatingStatus(true);
    await fetch(`/api/appointments/${id}/status`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ status }),
    });
    setSelectedApt(null);
    setUpdatingStatus(false);
    load();
  }, [load]);

  // Current time indicator position
  const currentTimeTop = useMemo(() => {
    const mins = minutesSinceDayStart(now);
    if (mins < 0 || mins > TOTAL_MINUTES) return null;
    return (mins / TOTAL_MINUTES) * 100;
  }, [now]);

  const headerLabel = useMemo(() => {
    if (view === "week") return formatDateRange(monday);
    return currentDate.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric", year: "numeric" });
  }, [view, monday, currentDate]);

  if (loading) {
    return (
      <div className="flex items-center justify-center h-[60vh]">
        <div className="w-8 h-8 border-[2.5px] border-primary-100 border-t-primary-500 rounded-full animate-spin" />
      </div>
    );
  }

  return (
    <div className="animate-fade-in h-full flex flex-col">
      {/* Header */}
      <div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 mb-4">
        <div className="flex items-center gap-2">
          <button onClick={() => navigate(-1)} className="p-2 hover:bg-gray-100 rounded-lg transition-colors">
            <ChevronLeft size={18} className="text-gray-500" />
          </button>
          <button onClick={goToday} className="px-3 py-1.5 text-xs font-semibold text-gray-600 hover:bg-gray-100 rounded-lg transition-colors">
            Today
          </button>
          <button onClick={() => navigate(1)} className="p-2 hover:bg-gray-100 rounded-lg transition-colors">
            <ChevronRight size={18} className="text-gray-500" />
          </button>
          <h1 className="text-lg font-bold text-gray-900 ml-2">{headerLabel}</h1>
        </div>
        <div className="flex items-center gap-2">
          <div className="flex bg-gray-100 rounded-lg p-0.5">
            <button onClick={() => setView("week")}
              className={`px-3 py-1.5 text-xs font-semibold rounded-md transition-all ${view === "week" ? "bg-white text-gray-900 shadow-sm" : "text-gray-400"}`}>
              Week
            </button>
            <button onClick={() => setView("day")}
              className={`px-3 py-1.5 text-xs font-semibold rounded-md transition-all ${view === "day" ? "bg-white text-gray-900 shadow-sm" : "text-gray-400"}`}>
              Day
            </button>
          </div>
          <button onClick={() => { setQuickBookSlot({ date: new Date(), time: "" }); setQbForm({ name: "", phone: "", treatmentId: "" }); setShowQuickBook(true); }}
            className="btn-primary btn-sm">
            <Plus size={15} /> Book
          </button>
        </div>
      </div>

      {/* Day headers */}
      <div className="flex border-b border-gray-200">
        <div className="w-16 shrink-0" />
        {visibleDays.map((day, i) => {
          const isToday = isSameDay(day, now);
          return (
            <div key={i} className={`flex-1 text-center py-2 border-l border-gray-100 ${isToday ? "bg-blue-50/50" : ""}`}>
              <p className="text-[10px] font-semibold text-gray-400 uppercase">
                {day.toLocaleDateString("en-US", { weekday: "short" })}
              </p>
              <p className={`text-lg font-bold ${isToday ? "text-primary-600" : "text-gray-800"}`}>
                {day.getDate()}
              </p>
            </div>
          );
        })}
      </div>

      {/* Time grid */}
      <div className="flex-1 overflow-auto relative" ref={gridRef} style={{ minHeight: 600 }}>
        <div className="flex relative" style={{ height: timeSlots.length * 48 }}>
          {/* Time labels */}
          <div className="w-16 shrink-0 relative">
            {timeSlots.map((slot, i) => (
              i % 2 === 0 ? (
                <div key={slot} className="absolute right-2 text-[11px] text-gray-400 font-medium" style={{ top: i * 48 - 7 }}>
                  {slot}
                </div>
              ) : null
            ))}
          </div>

          {/* Day columns */}
          {visibleDays.map((day, dayIdx) => {
            const isToday = isSameDay(day, now);
            const dayApts = getAptsForDay(day);

            return (
              <div key={dayIdx} className={`flex-1 relative border-l border-gray-100 ${isToday ? "bg-blue-50/30" : ""}`}>
                {/* Grid lines */}
                {timeSlots.map((slot, i) => (
                  <div key={slot}
                    className={`absolute left-0 right-0 border-t cursor-pointer hover:bg-gray-50/80 transition-colors ${i % 2 === 0 ? "border-gray-200" : "border-gray-100/50"}`}
                    style={{ top: i * 48, height: 48 }}
                    onClick={() => handleSlotClick(day, slot)}
                  />
                ))}

                {/* Current time indicator */}
                {isToday && currentTimeTop !== null && (
                  <div className="absolute left-0 right-0 z-20 pointer-events-none" style={{ top: `${currentTimeTop}%` }}>
                    <div className="flex items-center">
                      <div className="w-2.5 h-2.5 rounded-full bg-red-500 -ml-1" />
                      <div className="flex-1 h-[2px] bg-red-500" />
                    </div>
                  </div>
                )}

                {/* Appointments */}
                {dayApts.map(apt => {
                  const dt = new Date(apt.dateTime);
                  const mins = minutesSinceDayStart(dt);
                  if (mins < 0 || mins >= TOTAL_MINUTES) return null;
                  const duration = apt.treatment.duration || 30;
                  const topPx = (mins / 30) * 48;
                  const heightPx = Math.max((duration / 30) * 48, 24);
                  const color = STATUS_COLORS[apt.status] || "#6366f1";
                  const isCancelled = apt.status === "cancelled" || apt.status === "no_show";

                  return (
                    <div key={apt.id}
                      className={`absolute left-1 right-1 rounded-lg px-2 py-1 cursor-pointer overflow-hidden z-10 transition-all hover:shadow-md hover:scale-[1.02] ${isCancelled ? "opacity-50" : ""}`}
                      style={{
                        top: topPx,
                        height: heightPx,
                        backgroundColor: color + "18",
                        borderLeft: `3px solid ${color}`,
                      }}
                      onClick={(e) => handleAptClick(apt, e)}
                    >
                      <p className="text-[11px] font-bold text-gray-800 truncate leading-tight">{apt.lead.name}</p>
                      {heightPx > 30 && (
                        <p className="text-[10px] text-gray-500 truncate">{apt.treatment.name}</p>
                      )}
                      {heightPx > 50 && (
                        <p className="text-[9px] font-semibold mt-0.5" style={{ color }}>
                          {STATUS_LABELS[apt.status] || apt.status}
                        </p>
                      )}
                    </div>
                  );
                })}
              </div>
            );
          })}
        </div>
      </div>

      {/* Appointment detail popover */}
      {selectedApt && popoverPos && (
        <>
          <div className="fixed inset-0 z-40" onClick={() => setSelectedApt(null)} />
          <div className="fixed z-50 w-72 card p-4 shadow-xl animate-fade-in"
            style={{
              left: Math.min(popoverPos.x - 144, window.innerWidth - 300),
              top: Math.min(popoverPos.y, window.innerHeight - 300),
            }}>
            <div className="flex items-center justify-between mb-3">
              <h3 className="font-bold text-sm text-gray-900">{selectedApt.lead.name}</h3>
              <button onClick={() => setSelectedApt(null)} className="p-1 hover:bg-gray-100 rounded-lg">
                <X size={14} className="text-gray-400" />
              </button>
            </div>
            <div className="space-y-2 text-xs text-gray-500 mb-3">
              <div className="flex items-center gap-2">
                <Phone size={12} /> {selectedApt.lead.phone}
              </div>
              <div className="flex items-center gap-2">
                <Stethoscope size={12} /> {selectedApt.treatment.name} ({selectedApt.treatment.duration}min)
              </div>
              <div className="flex items-center gap-2">
                <Clock size={12} />
                {new Date(selectedApt.dateTime).toLocaleString("en-US", {
                  weekday: "short", month: "short", day: "numeric",
                  hour: "numeric", minute: "2-digit",
                })}
              </div>
              <div className="flex items-center gap-2">
                <span className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: STATUS_COLORS[selectedApt.status] || "#6366f1" }} />
                <span className="font-semibold" style={{ color: STATUS_COLORS[selectedApt.status] }}>
                  {STATUS_LABELS[selectedApt.status] || selectedApt.status}
                </span>
              </div>
            </div>
            <div className="flex gap-2">
              {selectedApt.status === "scheduled" && (
                <>
                  <button disabled={updatingStatus} onClick={() => updateStatus(selectedApt.id, "confirmed")}
                    className="flex-1 px-3 py-2 text-xs font-semibold bg-emerald-600 hover:bg-emerald-700 text-white rounded-lg transition-colors">
                    ✅ Confirm
                  </button>
                  <button disabled={updatingStatus} onClick={() => updateStatus(selectedApt.id, "cancelled")}
                    className="flex-1 px-3 py-2 text-xs font-semibold bg-gray-100 hover:bg-gray-200 text-gray-600 rounded-lg transition-colors">
                    Cancel
                  </button>
                </>
              )}
              {selectedApt.status === "confirmed" && (
                <>
                  <button disabled={updatingStatus} onClick={() => updateStatus(selectedApt.id, "arrived")}
                    className="flex-1 px-3 py-2 text-xs font-semibold bg-emerald-600 hover:bg-emerald-700 text-white rounded-lg transition-colors">
                    🏥 Arrived
                  </button>
                  <button disabled={updatingStatus} onClick={() => updateStatus(selectedApt.id, "no_show")}
                    className="flex-1 px-3 py-2 text-xs font-semibold bg-gray-100 hover:bg-gray-200 text-gray-600 rounded-lg transition-colors">
                    No Show
                  </button>
                </>
              )}
              {selectedApt.status === "arrived" && (
                <button disabled={updatingStatus} onClick={() => updateStatus(selectedApt.id, "in_progress")}
                  className="flex-1 px-3 py-2 text-xs font-semibold bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg transition-colors">
                  ▶ Start
                </button>
              )}
              {selectedApt.status === "in_progress" && (
                <button disabled={updatingStatus} onClick={() => updateStatus(selectedApt.id, "completed")}
                  className="flex-1 px-3 py-2 text-xs font-semibold bg-emerald-600 hover:bg-emerald-700 text-white rounded-lg transition-colors">
                  🎉 Complete
                </button>
              )}
            </div>
          </div>
        </>
      )}

      {/* Quick book modal */}
      {showQuickBook && (
        <div className="modal-overlay" onClick={() => setShowQuickBook(false)}>
          <div className="card p-6 w-full max-w-sm animate-scale-in" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <h2 className="text-base font-bold">Quick Book</h2>
              <button onClick={() => setShowQuickBook(false)} className="p-1.5 hover:bg-gray-100 rounded-lg text-gray-400">
                <X size={18} />
              </button>
            </div>
            {quickBookSlot && quickBookSlot.time && (
              <p className="text-xs text-gray-400 mb-3">
                {quickBookSlot.date.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" })} at {quickBookSlot.time}
              </p>
            )}
            <form onSubmit={handleQuickBook} className="space-y-3">
              <input type="text" value={qbForm.name} onChange={e => setQbForm(p => ({ ...p, name: e.target.value }))}
                placeholder="Patient name" required className="input" autoFocus />
              <input type="tel" value={qbForm.phone} onChange={e => setQbForm(p => ({ ...p, phone: e.target.value }))}
                placeholder="+966 5X XXX XXXX" required className="input" />
              <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)</option>)}
              </select>
              {(!quickBookSlot?.time) && (
                <input type="datetime-local" className="input"
                  onChange={e => {
                    if (e.target.value) {
                      setQuickBookSlot({ date: new Date(e.target.value), time: e.target.value });
                    }
                  }} required />
              )}
              <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..." : "⚡ Book"}
                </button>
              </div>
            </form>
          </div>
        </div>
      )}
    </div>
  );
}
