"use client";
import { useState, useEffect } from "react";
import {
  ChevronLeft,
  ChevronRight,
  Calendar,
  Zap,
  RefreshCw,
  Filter,
  Download,
  Sun,
  Moon,
  Sunset,
  Clock,
} from "lucide-react";
import {
  format,
  startOfMonth,
  endOfMonth,
  eachDayOfInterval,
  isSameMonth,
  isToday,
  parseISO,
  addMonths,
  subMonths,
  startOfWeek,
  endOfWeek,
} from "date-fns";
import { cn, formatTime } from "@/lib/utils";
import Badge from "./ui/Badge";
import Avatar from "./ui/Avatar";

interface Employee {
  id: number;
  firstName: string;
  lastName: string;
  rank: string | null;
  role: string;
  orgNodeId: number | null;
  avatarColor: string | null;
  badgeNumber: string | null;
}

interface OrgNode {
  id: number;
  name: string;
  type: string;
  color: string | null;
  parentId: number | null;
}

interface Schedule {
  id: number;
  employeeId: number;
  orgNodeId: number | null;
  shiftTemplateId: number | null;
  date: string;
  startTime: string;
  endTime: string;
  shiftType: string | null;
  notes: string | null;
  isOverride: boolean | null;
}

interface RotationConfig {
  id: number;
  name: string;
  patternKey: string;
  rotationDays: number;
  shiftHours: number;
  startDate: string;
  dayNightRotation: boolean;
  dayNightIntervalDays: number;
  generatedThrough: string | null;
  isActive: boolean | null;
  orgNodeId: number | null;
  squads?: Array<{ orgNodeId: number; offsetDays: number; startsOnNights: boolean }>;
}

interface ShiftTemplate {
  id: number;
  name: string;
  type: string;
  startTime: string;
  endTime: string;
  color: string | null;
}

interface SchedulerProps {
  departmentId: number;
  employees: Employee[];
  orgNodes: OrgNode[];
  rotationConfigs: RotationConfig[];
  shiftTemplates: ShiftTemplate[];
}

const SHIFT_COLORS: Record<string, string> = {
  day: "#3B82F6",
  evening: "#F59E0B",
  night: "#8B5CF6",
  custom: "#10B981",
};

const SHIFT_ICONS: Record<string, React.ElementType> = {
  day: Sun,
  evening: Sunset,
  night: Moon,
  custom: Clock,
};

export default function Scheduler({ departmentId, employees, orgNodes, rotationConfigs, shiftTemplates }: SchedulerProps) {
  const [currentDate, setCurrentDate] = useState(new Date());
  const [schedules, setSchedules] = useState<Schedule[]>([]);
  const [loading, setLoading] = useState(false);
  const [generating, setGenerating] = useState(false);
  const [view, setView] = useState<"month" | "week" | "roster">("month");
  const [filterNodeId, setFilterNodeId] = useState<number | null>(null);
  const [selectedRotation, setSelectedRotation] = useState<number | null>(null);
  const [showGenerateModal, setShowGenerateModal] = useState(false);
  const [generateForm, setGenerateForm] = useState({
    startDate: format(new Date(), "yyyy-MM-dd"),
    endDate: format(new Date(new Date().getFullYear(), 11, 31), "yyyy-MM-dd"),
    rotationConfigId: rotationConfigs[0]?.id ?? null,
    orgNodeId: null as number | null,
    clearExisting: true,
  });
  const [generatedResult, setGeneratedResult] = useState<{ generated: number; employees: number; days: number } | null>(null);
  const [syncing, setSyncing] = useState(false);
  const [syncMsg, setSyncMsg] = useState<string | null>(null);

  const handleSync = async () => {
    setSyncing(true);
    try {
      const res = await fetch("/api/schedules/sync", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ departmentId }),
      });
      const data = await res.json();
      if (data.success) {
        setSyncMsg(
          data.rotationsSynced === 0
            ? "Nothing to sync — build a year first with Auto-Generate."
            : `Rebuilt ${data.rowsRebuilt.toLocaleString()} shifts across ${data.rotationsSynced} rotation(s).`
        );
        await fetchSchedules();
      } else {
        setSyncMsg(data.error ?? "Sync failed");
      }
      setTimeout(() => setSyncMsg(null), 4000);
    } finally {
      setSyncing(false);
    }
  };

  const fetchSchedules = async () => {
    setLoading(true);
    try {
      const start = format(startOfMonth(subMonths(currentDate, 0)), "yyyy-MM-dd");
      const end = format(endOfMonth(currentDate), "yyyy-MM-dd");
      const params = new URLSearchParams({ startDate: start, endDate: end });
      if (filterNodeId) params.append("orgNodeId", String(filterNodeId));
      const res = await fetch(`/api/schedules?${params}`);
      const data = await res.json();
      setSchedules(Array.isArray(data) ? data : []);
    } catch (e) {
      console.error(e);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchSchedules();
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [currentDate, filterNodeId]);

  const handleGenerate = async () => {
    setGenerating(true);
    setGeneratedResult(null);
    try {
      const res = await fetch("/api/schedules/generate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          departmentId,
          ...generateForm,
          rotationConfigId: generateForm.rotationConfigId || null,
          orgNodeId: generateForm.orgNodeId || null,
        }),
      });
      const data = await res.json();
      if (data.success) {
        setGeneratedResult({ generated: data.generated, employees: data.employees, days: data.days });
        await fetchSchedules();
      } else {
        alert("Error: " + (data.error ?? "Unknown error"));
      }
    } catch (e) {
      console.error(e);
    } finally {
      setGenerating(false);
    }
  };

  // Calendar grid
  const monthStart = startOfMonth(currentDate);
  const monthEnd = endOfMonth(currentDate);
  const calStart = startOfWeek(monthStart, { weekStartsOn: 0 });
  const calEnd = endOfWeek(monthEnd, { weekStartsOn: 0 });
  const calDays = eachDayOfInterval({ start: calStart, end: calEnd });

  const getSchedulesForDay = (date: Date) => {
    const dateStr = format(date, "yyyy-MM-dd");
    return schedules.filter((s) => s.date === dateStr);
  };

  const getEmployeeById = (id: number) => employees.find((e) => e.id === id);
  const getNodeById = (id: number | null) => id ? orgNodes.find((n) => n.id === id) : null;

  // Week view
  const weekStart = startOfWeek(currentDate, { weekStartsOn: 0 });
  const weekDays = eachDayOfInterval({ start: weekStart, end: endOfWeek(currentDate, { weekStartsOn: 0 }) });

  const filteredEmployees = filterNodeId
    ? employees.filter((e) => e.orgNodeId === filterNodeId)
    : employees;

  return (
    <div>
      {/* Toolbar */}
      <div className="flex flex-wrap items-center justify-between gap-3 mb-6">
        <div className="flex items-center gap-2">
          <button
            onClick={() => setCurrentDate(subMonths(currentDate, 1))}
            className="p-2 rounded-xl border border-slate-200 hover:bg-slate-50 transition-colors"
          >
            <ChevronLeft size={18} />
          </button>
          <h3 className="text-lg font-bold text-slate-800 min-w-[160px] text-center">
            {format(currentDate, "MMMM yyyy")}
          </h3>
          <button
            onClick={() => setCurrentDate(addMonths(currentDate, 1))}
            className="p-2 rounded-xl border border-slate-200 hover:bg-slate-50 transition-colors"
          >
            <ChevronRight size={18} />
          </button>
          <button
            onClick={() => setCurrentDate(new Date())}
            className="px-3 py-1.5 text-sm border border-slate-200 rounded-xl hover:bg-slate-50 transition-colors"
          >
            Today
          </button>
        </div>

        <div className="flex items-center gap-2 flex-wrap">
          {/* View toggle */}
          <div className="flex bg-slate-100 rounded-xl p-1">
            {(["month", "week", "roster"] as const).map((v) => (
              <button
                key={v}
                onClick={() => setView(v)}
                className={cn(
                  "px-3 py-1 rounded-lg text-sm font-medium transition-colors capitalize",
                  view === v ? "bg-white text-blue-600 shadow-sm" : "text-slate-500 hover:text-slate-700"
                )}
              >
                {v}
              </button>
            ))}
          </div>

          {/* Filter by unit */}
          <select
            value={filterNodeId ?? ""}
            onChange={(e) => setFilterNodeId(e.target.value ? parseInt(e.target.value) : null)}
            className="border border-slate-200 rounded-xl px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
          >
            <option value="">All Units</option>
            {orgNodes.map((n) => (
              <option key={n.id} value={n.id}>{n.name}</option>
            ))}
          </select>

          <button
            onClick={() => setShowGenerateModal(true)}
            className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-xl text-sm font-medium hover:bg-blue-700 transition-colors"
          >
            <Zap size={16} />
            Auto-Generate
          </button>

          <button
            onClick={handleSync}
            disabled={syncing}
            className="flex items-center gap-2 px-3 py-2 border border-slate-200 rounded-xl text-sm font-medium text-slate-600 hover:bg-slate-50 transition-colors disabled:opacity-50"
            title="Rebuild upcoming shifts from the current org chart"
          >
            <RefreshCw size={15} className={syncing ? "animate-spin" : ""} />
            Re-sync
          </button>

          <button
            onClick={fetchSchedules}
            className="p-2 border border-slate-200 rounded-xl hover:bg-slate-50 transition-colors"
            title="Refresh"
          >
            <RefreshCw size={16} className={loading ? "animate-spin" : ""} />
          </button>
        </div>
      </div>

      {syncMsg && (
        <div className="mb-4 flex items-center gap-2 bg-blue-50 border border-blue-200 text-blue-700 rounded-xl px-4 py-2.5 text-sm">
          <RefreshCw size={15} /> {syncMsg}
        </div>
      )}

      {/* Active rotations summary */}
      {rotationConfigs.length > 0 && (
        <div className="flex flex-wrap gap-2 mb-4">
          {rotationConfigs.map((rc) => (
            <div
              key={rc.id}
              className="flex items-center gap-2 bg-slate-50 border border-slate-200 rounded-xl px-3 py-1.5 text-xs"
            >
              <span className="font-semibold text-slate-700">{rc.name}</span>
              <Badge color="#2563EB">{rc.rotationDays}d cycle</Badge>
              {rc.dayNightRotation && (
                <Badge color="#7C3AED">D/N swap {rc.dayNightIntervalDays}d</Badge>
              )}
              {rc.generatedThrough && (
                <span className="text-slate-400">thru {rc.generatedThrough}</span>
              )}
            </div>
          ))}
        </div>
      )}

      {/* Shift Legend */}
      <div className="flex gap-4 mb-4 flex-wrap">
        {shiftTemplates.map((t) => {
          const Icon = SHIFT_ICONS[t.type] ?? Clock;
          return (
            <div key={t.id} className="flex items-center gap-1.5 text-xs text-slate-600">
              <div
                className="w-3 h-3 rounded-full"
                style={{ backgroundColor: t.color ?? SHIFT_COLORS[t.type] ?? "#3B82F6" }}
              />
              <Icon size={12} />
              <span>{t.name} ({t.startTime}–{t.endTime})</span>
            </div>
          );
        })}
      </div>

      {/* Month View */}
      {view === "month" && (
        <div>
          <div className="grid grid-cols-7 mb-1">
            {["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"].map((d) => (
              <div key={d} className="text-center text-xs font-semibold text-slate-400 py-2">{d}</div>
            ))}
          </div>
          <div className="grid grid-cols-7 gap-1">
            {calDays.map((day) => {
              const daySchedules = getSchedulesForDay(day);
              const inMonth = isSameMonth(day, currentDate);
              const today = isToday(day);
              return (
                <div
                  key={day.toISOString()}
                  className={cn(
                    "min-h-[90px] p-1.5 rounded-xl border transition-colors",
                    inMonth ? "bg-white border-slate-200" : "bg-slate-50 border-transparent",
                    today && "border-blue-400 bg-blue-50"
                  )}
                >
                  <span
                    className={cn(
                      "text-xs font-semibold inline-flex items-center justify-center w-6 h-6 rounded-full",
                      today ? "bg-blue-600 text-white" : inMonth ? "text-slate-700" : "text-slate-300"
                    )}
                  >
                    {format(day, "d")}
                  </span>
                  <div className="mt-1 space-y-0.5">
                    {daySchedules.slice(0, 3).map((s) => {
                      const emp = getEmployeeById(s.employeeId);
                      if (!emp) return null;
                      const color = SHIFT_COLORS[s.shiftType ?? "day"] ?? "#3B82F6";
                      return (
                        <div
                          key={s.id}
                          className="flex items-center gap-1 rounded px-1 py-0.5 text-white text-xs truncate"
                          style={{ backgroundColor: color + "dd" }}
                          title={`${emp.firstName} ${emp.lastName} — ${formatTime(s.startTime)}`}
                        >
                          <span className="font-medium truncate">{emp.firstName[0]}. {emp.lastName}</span>
                        </div>
                      );
                    })}
                    {daySchedules.length > 3 && (
                      <div className="text-xs text-slate-400 pl-1">+{daySchedules.length - 3} more</div>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      )}

      {/* Week View */}
      {view === "week" && (
        <div>
          <div className="grid grid-cols-8 border-b border-slate-200 pb-2 mb-2">
            <div className="text-xs text-slate-400 font-semibold">Officer</div>
            {weekDays.map((d) => (
              <div key={d.toISOString()} className={cn("text-center text-xs font-semibold", isToday(d) ? "text-blue-600" : "text-slate-500")}>
                <div>{format(d, "EEE")}</div>
                <div className={cn("text-lg font-bold", isToday(d) ? "text-blue-600" : "text-slate-800")}>{format(d, "d")}</div>
              </div>
            ))}
          </div>
          <div className="space-y-2 max-h-[500px] overflow-y-auto">
            {filteredEmployees.map((emp) => (
              <div key={emp.id} className="grid grid-cols-8 items-center gap-1">
                <div className="flex items-center gap-2">
                  <Avatar firstName={emp.firstName} lastName={emp.lastName} color={emp.avatarColor ?? "#3B82F6"} size="sm" />
                  <div className="min-w-0">
                    <p className="text-xs font-medium text-slate-700 truncate">{emp.firstName} {emp.lastName}</p>
                    <p className="text-xs text-slate-400 truncate">{emp.rank}</p>
                  </div>
                </div>
                {weekDays.map((day) => {
                  const dateStr = format(day, "yyyy-MM-dd");
                  const empSchedules = schedules.filter((s) => s.employeeId === emp.id && s.date === dateStr);
                  return (
                    <div key={day.toISOString()} className={cn("rounded-lg p-1 min-h-[44px]", isToday(day) ? "bg-blue-50" : "bg-slate-50")}>
                      {empSchedules.map((s) => {
                        const color = SHIFT_COLORS[s.shiftType ?? "day"] ?? "#3B82F6";
                        const Icon = SHIFT_ICONS[s.shiftType ?? "day"] ?? Clock;
                        return (
                          <div
                            key={s.id}
                            className="text-white text-xs rounded px-1 py-0.5 flex items-center gap-1"
                            style={{ backgroundColor: color }}
                          >
                            <Icon size={10} />
                            <span>{s.startTime}</span>
                          </div>
                        );
                      })}
                      {empSchedules.length === 0 && (
                        <span className="text-xs text-slate-300">—</span>
                      )}
                    </div>
                  );
                })}
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Roster View */}
      {view === "roster" && (
        <div className="space-y-6">
          {orgNodes.filter((n) => !filterNodeId || n.id === filterNodeId).map((node) => {
            const nodeEmployees = employees.filter((e) => e.orgNodeId === node.id);
            const today = format(new Date(), "yyyy-MM-dd");
            const todaySchedules = schedules.filter((s) => s.date === today && nodeEmployees.some((e) => e.id === s.employeeId));
            return (
              <div key={node.id} className="bg-white rounded-2xl border border-slate-200 overflow-hidden">
                <div
                  className="flex items-center justify-between px-5 py-3"
                  style={{ backgroundColor: (node.color ?? "#3B82F6") + "22", borderLeft: `4px solid ${node.color ?? "#3B82F6"}` }}
                >
                  <div>
                    <h4 className="font-bold text-slate-800">{node.name}</h4>
                    <p className="text-xs text-slate-500">{nodeEmployees.length} officers assigned</p>
                  </div>
                  <Badge color={node.color ?? "#3B82F6"}>
                    {todaySchedules.length} on shift today
                  </Badge>
                </div>
                <div className="p-4">
                  <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
                    {nodeEmployees.map((emp) => {
                      const todayShift = todaySchedules.find((s) => s.employeeId === emp.id);
                      const color = todayShift ? (SHIFT_COLORS[todayShift.shiftType ?? "day"] ?? "#3B82F6") : "#94A3B8";
                      return (
                        <div key={emp.id} className="flex items-center gap-3 p-3 rounded-xl bg-slate-50 border border-slate-100">
                          <Avatar firstName={emp.firstName} lastName={emp.lastName} color={emp.avatarColor ?? "#3B82F6"} size="sm" />
                          <div className="flex-1 min-w-0">
                            <p className="text-sm font-semibold text-slate-800 truncate">{emp.firstName} {emp.lastName}</p>
                            <p className="text-xs text-slate-500">{emp.rank} • #{emp.badgeNumber}</p>
                          </div>
                          <div
                            className="text-xs font-medium px-2 py-1 rounded-lg text-white"
                            style={{ backgroundColor: color }}
                          >
                            {todayShift ? formatTime(todayShift.startTime) : "Off"}
                          </div>
                        </div>
                      );
                    })}
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      )}

      {/* Generate Modal */}
      {showGenerateModal && (
        <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
          <div className="absolute inset-0 bg-black/50 backdrop-blur-sm" onClick={() => { setShowGenerateModal(false); setGeneratedResult(null); }} />
          <div className="relative bg-white rounded-2xl shadow-2xl w-full max-w-lg">
            <div className="p-6 border-b border-slate-100">
              <h2 className="text-xl font-bold text-slate-800 flex items-center gap-2">
                <Zap className="text-blue-500" size={22} />
                Auto-Generate Schedule
              </h2>
              <p className="text-sm text-slate-500 mt-1">Automatically create the full-year schedule based on rotation configurations</p>
            </div>
            <div className="p-6 space-y-4">
              {generatedResult ? (
                <div className="text-center py-6">
                  <div className="w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-4">
                    <Zap className="text-green-500" size={32} />
                  </div>
                  <h3 className="text-xl font-bold text-slate-800 mb-2">Schedule Generated!</h3>
                  <div className="grid grid-cols-3 gap-4 mt-4">
                    <div className="bg-blue-50 rounded-xl p-3">
                      <div className="text-2xl font-bold text-blue-600">{generatedResult.generated}</div>
                      <div className="text-xs text-slate-500">Shifts Created</div>
                    </div>
                    <div className="bg-green-50 rounded-xl p-3">
                      <div className="text-2xl font-bold text-green-600">{generatedResult.employees}</div>
                      <div className="text-xs text-slate-500">Employees</div>
                    </div>
                    <div className="bg-purple-50 rounded-xl p-3">
                      <div className="text-2xl font-bold text-purple-600">{generatedResult.days}</div>
                      <div className="text-xs text-slate-500">Days Covered</div>
                    </div>
                  </div>
                  <button
                    onClick={() => { setShowGenerateModal(false); setGeneratedResult(null); }}
                    className="mt-6 px-6 py-2.5 bg-blue-600 text-white rounded-xl font-medium hover:bg-blue-700 transition-colors"
                  >
                    Done
                  </button>
                </div>
              ) : (
                <>
                  <div className="grid grid-cols-2 gap-4">
                    <div>
                      <label className="block text-sm font-medium text-slate-700 mb-1">Start Date</label>
                      <input
                        type="date"
                        value={generateForm.startDate}
                        onChange={(e) => setGenerateForm({ ...generateForm, startDate: e.target.value })}
                        className="w-full border border-slate-300 rounded-xl px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
                      />
                    </div>
                    <div>
                      <label className="block text-sm font-medium text-slate-700 mb-1">End Date</label>
                      <input
                        type="date"
                        value={generateForm.endDate}
                        onChange={(e) => setGenerateForm({ ...generateForm, endDate: e.target.value })}
                        className="w-full border border-slate-300 rounded-xl px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
                      />
                    </div>
                  </div>

                  <div>
                    <label className="block text-sm font-medium text-slate-700 mb-1">Rotation Plan</label>
                    <select
                      value={generateForm.rotationConfigId ?? ""}
                      onChange={(e) => setGenerateForm({ ...generateForm, rotationConfigId: e.target.value ? parseInt(e.target.value) : null as unknown as number })}
                      className="w-full border border-slate-300 rounded-xl px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
                    >
                      <option value="">All active rotations (entire department)</option>
                      {rotationConfigs.map((rc) => (
                        <option key={rc.id} value={rc.id}>
                          {rc.name} — {rc.rotationDays}-day cycle
                          {rc.dayNightRotation ? `, D/N swap every ${rc.dayNightIntervalDays}d` : ", fixed shifts"}
                        </option>
                      ))}
                    </select>
                    {rotationConfigs.length === 0 && (
                      <p className="text-xs text-amber-600 mt-1">
                        No rotations yet — create one on the Rotations tab (Pitman, Kelly, Panama, DuPont…).
                      </p>
                    )}
                  </div>

                  <label className="flex items-center gap-3 cursor-pointer">
                    <input
                      type="checkbox"
                      checked={generateForm.clearExisting}
                      onChange={(e) => setGenerateForm({ ...generateForm, clearExisting: e.target.checked })}
                      className="w-4 h-4 rounded border-slate-300 text-blue-600"
                    />
                    <span className="text-sm text-slate-700">Replace existing generated shifts in this range (manual overrides are kept)</span>
                  </label>

                  <div className="bg-amber-50 border border-amber-200 rounded-xl p-3 text-sm text-amber-700">
                    <strong>How it works:</strong> Each squad in the rotation is phased through the selected plan and
                    swaps days/nights on the interval you chose. Every active officer in a squad inherits that squad&apos;s
                    shifts, so the calendar re-adjusts automatically whenever staff are added, moved, or removed.
                  </div>

                  <div className="flex gap-3 pt-2">
                    <button
                      onClick={handleGenerate}
                      disabled={generating}
                      className="flex-1 py-2.5 bg-blue-600 text-white rounded-xl font-medium hover:bg-blue-700 transition-colors disabled:opacity-50 flex items-center justify-center gap-2"
                    >
                      {generating ? (
                        <><RefreshCw size={16} className="animate-spin" /> Generating...</>
                      ) : (
                        <><Zap size={16} /> Generate Schedule</>
                      )}
                    </button>
                    <button
                      onClick={() => setShowGenerateModal(false)}
                      className="px-4 py-2.5 border border-slate-200 rounded-xl text-slate-600 hover:bg-slate-50 transition-colors"
                    >
                      Cancel
                    </button>
                  </div>
                </>
              )}
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
