import React, { useState, useRef, useEffect, Fragment } from "react";
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin, { Draggable } from "@fullcalendar/interaction";
import { Dialog, Transition } from "@headlessui/react";
import { Plus, Calendar, Search, X } from "lucide-react";
import { initialCasesSeed } from "@/constant/data";
import { useNavigate } from "react-router-dom";

/**
 * Single-file component: CaseScheduler
 *
 * Requirements:
 * - Headless UI Dialog for modals
 * - <input type="datetime-local"> for datetime selection
 * - FullCalendar with external draggable items (Draggable)
 *
 * Note: Tailwind CSS classes used for styling.
 */

const priorityColorMap = {
  High: "#ef4444", // red
  Medium: "#f97316", // orange
  Low: "#3b82f6", // blue
};

const thicknessOptions = ["5mm", "6mm", "8mm", "10mm", "12mm"];
const categoryList = ["All", "TH", "TL", "FLSS", "LM", "TP"];

export default function CaseScheduler() {
  const navigate = useNavigate();
  const [cases, setCases] = useState(initialCasesSeed);
  const [events, setEvents] = useState([]);
  const [filter, setFilter] = useState("");
  const [category, setCategory] = useState("FLSS");
  const [calendarView, setCalendarView] = useState("timeGridWeek");

  // Modals state
  const [showPlaceModal, setShowPlaceModal] = useState(false);
  const [showNewModal, setShowNewModal] = useState(false);

  // Selected case for Place modal
  const [selectedCaseId, setSelectedCaseId] = useState(null);
  const [placeForm, setPlaceForm] = useState({
    order: "",
    thickness: "8mm",
    requested: "",
    datetime: "", // ISO-like: "2025-10-04T09:00"
    priority: "Medium",
    notes: "",
  });

  // New case form
  const [newForm, setNewForm] = useState({
    name: "",
    category: category,
    priority: "Medium",
    notes: "",
    datetime: "",
  });

  const calendarRef = useRef();

  // filtered list
  const filteredCases = cases.filter((c) => {
    const matchCat = c.category === category;
    const text = (filter || "").toLowerCase();
    const matchSearch =
      c.id.toLowerCase().includes(text) ||
      (c.name || "").toLowerCase().includes(text) ||
      (c.type || "").toLowerCase().includes(text) ||
      (c.sales || "").toLowerCase().includes(text) ||
      (c.description || "").toLowerCase().includes(text);

    // Hide rejected and scheduled from list
    const visibleStatus = c.status !== "Rejected" && c.status !== "Scheduled";

    return matchCat && matchSearch && visibleStatus;
  });

  // Preload scheduled events based on data
  useEffect(() => {
    const scheduledEvents = initialCasesSeed
      .filter((c) => c.scheduled && c.category === category)
      .map((c) => ({
        id: c.id + "-" + new Date(c.scheduled).getTime(),
        title: `${c.id} - ${c.name}`,
        start: new Date(c.scheduled),
        end: new Date(new Date(c.scheduled).getTime() + 2 * 60 * 60 * 1000),
        backgroundColor: priorityColorMap[c.priority],
        borderColor: priorityColorMap[c.priority],
      }));
    setEvents(scheduledEvents);

    // also make sure their status is "Scheduled"
    setCases((prev) =>
      prev.map((c) =>
        c.scheduled ? { ...c, status: "Scheduled" } : c
      )
    );
  }, []);

  // Setup FullCalendar Draggable for external elements.
  useEffect(() => {
    const containerEl = document.getElementById("external-cases");
    if (!containerEl) return;

    // clean old draggable if exists
    if (containerEl._draggableInstance) {
      containerEl._draggableInstance.destroy();
    }

    const draggable = new Draggable(containerEl, {
      itemSelector: ".fc-draggable",
      eventData: (eventEl) => {
        const id = eventEl.getAttribute("data-id");
        const found = cases.find((c) => c.id === id);
        if (!found || found.status === "Rejected") return null;
        return {
          id: found.id,
          title: `${found.id} - ${found.name}`,
          backgroundColor: priorityColorMap[found.priority],
          borderColor: priorityColorMap[found.priority],
        };
      },
    });

    containerEl._draggableInstance = draggable;

    return () => {
      draggable.destroy && draggable.destroy();
    };
  }, [cases]);


  // Handler for external item dropped on calendar
  // FullCalendar uses `drop` for external elements. The `info` contains .date and .draggedEl
  const handleExternalDrop = (info) => {
    const el = info.draggedEl;
    const caseId = el?.getAttribute("data-id");
    if (!caseId) return;
    const found = cases.find((c) => c.id === caseId);
    if (!found) return;

    setCases((prev) =>
      prev.map((c) =>
        c.id === caseId
          ? { ...c, status: "Scheduled", color: priorityColorMap[c.priority] }
          : c
      )
    );

    const start = info.date;
    const end = new Date(start.getTime() + 2 * 60 * 60 * 1000); // 2 hours duration
    const newEvent = {
      id: found.id + "-" + start.getTime(),
      title: `${found.id} - ${found.name}`,
      start,
      end,
      backgroundColor: priorityColorMap[found.priority],
      borderColor: priorityColorMap[found.priority],
    };
    setEvents((prev) => [...prev, newEvent]);
  };


  // Open Place modal for a specific case (from Place on Calendar button)
  function openPlaceModal(caseId) {
    const found = cases.find((c) => c.id === caseId);
    if (!found) return;
    setSelectedCaseId(caseId);
    setPlaceForm({
      order: found.order || "",
      thickness: found.thickness || "8mm",
      requested: found.requested || "",
      datetime: "", // user picks
      priority: found.priority || "Medium",
      notes: found.notes || "",
    });
    setShowPlaceModal(true);
  }

  // Approve & Place from the modal
  function approveAndPlace() {
    if (!selectedCaseId) return;
    const found = cases.find((c) => c.id === selectedCaseId);
    if (!found) return;

    // update case to Scheduled
    setCases((prev) =>
      prev.map((c) =>
        c.id === selectedCaseId
          ? { ...c, status: "Scheduled", priority: placeForm.priority, notes: placeForm.notes, thickness: placeForm.thickness }
          : c
      )
    );

    // add event at selected datetime
    if (!placeForm.datetime) {
      // if no datetime supplied, close modal and just mark scheduled
      setShowPlaceModal(false);
      return;
    }

    const start = new Date(placeForm.datetime);
    const end = new Date(start.getTime() + 2 * 60 * 60 * 1000);

    const ev = {
      id: found.id + "-" + start.getTime(),
      title: `${found.id} - ${found.name}`,
      start,
      end,
      backgroundColor: priorityColorMap[placeForm.priority] || "#3b82f6",
      borderColor: priorityColorMap[placeForm.priority] || "#3b82f6",
    };
    setEvents((prev) => [...prev, ev]);
    setShowPlaceModal(false);
  }

  // Save as pending (update case fields)
  function savePlaceAsPending() {
    if (!selectedCaseId) return;
    setCases((prev) =>
      prev.map((c) =>
        c.id === selectedCaseId
          ? {
              ...c,
              priority: placeForm.priority,
              notes: placeForm.notes,
              thickness: placeForm.thickness,
              // keep status as Pending unless it was Approved/Scheduled
            }
          : c
      )
    );
    setShowPlaceModal(false);
  }

  // Open New Case modal
  function openNewModal() {
    setNewForm({
      name: "",
      category: category,
      priority: "Medium",
      notes: "",
      datetime: "",
    });
    setShowNewModal(true);
  }

  // Save new case as pending
  function saveNewAsPending() {
    // create a simple UC- id by incrementing
    const maxNum = cases.reduce((max, c) => {
      const m = c.id && c.id.startsWith("UC-") ? parseInt(c.id.split("-")[1]) || 0 : 0;
      return Math.max(max, m);
    }, 1026);
    const newIdNum = maxNum + 1;
    const newId = `UC-${newIdNum}`;

    const newCase = {
      id: newId,
      order: String(100000 + newIdNum), // fake order
      category: newForm.category,
      name: newForm.name || newId,
      type: newForm.name || newId,
      requested: "",
      sales: "",
      description: newForm.notes || "",
      priority: newForm.priority,
      status: "Pending",
      color: priorityColorMap[newForm.priority],
      notes: newForm.notes,
      thickness: "8mm",
    };

    setCases((prev) => [newCase, ...prev]);
    setShowNewModal(false);

    // Optionally auto-place if datetime provided? The user requested only Save as Pending for new case.
  }

  // Approve and place directly from list approve button
  function handleApproveFromList(id) {
    setCases((prev) => prev.map((c) => (c.id === id ? { ...c, status: "Approved" } : c)));
  }

  function handleRejectFromList(id) {
    setCases((prev) =>
      prev.map((c) =>
        c.id === id ? { ...c, status: "Rejected" } : c
      )
    );
  }

  // Place on calendar via button in list: open place modal
  // Also implement drag behavior: pending or approved should be draggable (Draggable.filter above handles rejection)
  // For "Place on Calendar" button in the list we open the modal
  // The modal's Approve & Place will add event at chosen datetime

  return (
    <div>
      <div className="py-4 grid grid-cols-6 gap-3">
        {categoryList.map((cat) => (
          <button
            key={cat}
            onClick={() =>
              navigate(`/tasks/${cat === "All" ? "all" : cat.toLowerCase()}`)
            }
            className={`text-center px-4 py-2 rounded-lg border font-medium text-sm transition
              ${
                category === cat
                  ? "bg-blue-600 text-white border-blue-600"
                  : "bg-white text-gray-700 hover:bg-blue-50 hover:text-blue-600"
              }`}
          >
            {cat}
          </button>
        ))}
      </div>

      <div className="flex h-screen bg-gray-50">
        {/* Left panel */}
        <div className="w-1/3 bg-white border-r p-4 flex flex-col overflow-y-auto">
          <div className="flex justify-between items-center mb-4">
            <h2 className="text-lg font-semibold">Urgent Cases ({filteredCases.length})</h2>
            <button
              onClick={openNewModal}
              className="bg-blue-600 hover:bg-blue-700 text-white px-3 py-2 rounded-lg flex items-center gap-2 text-sm"
            >
              <Plus size={16} /> New Case
            </button>
          </div>

          {/* Search */}
          <div className="relative mb-3">
            <Search size={16} className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" />
            <input
              type="text"
              placeholder="Search by ID, name, type..."
              className="pl-9 pr-3 py-2 w-full border rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
              value={filter}
              onChange={(e) => setFilter(e.target.value)}
            />
          </div>

          {/* External cases container */}
          <div id="external-cases" className="pb-8">
            {filteredCases.map((item) => (
              <div
                key={item.id}
                data-id={item.id}
                className={`fc-draggable border rounded-xl p-4 mb-4 ${
                  item.status === "Rejected" ? "bg-gray-100 opacity-60 cursor-not-allowed" : "bg-white shadow-sm cursor-grab"
                }`}
              >
                <div className="flex justify-between items-start mb-2">
                  <div>
                    <div className="font-semibold">{item.id}</div>
                    <div className="text-gray-500 text-sm">Order {item.name}</div>
                  </div>

                  <div className="flex flex-col items-end gap-2">
                    <div className="flex gap-2 items-center">
                      <span
                        className={`text-xs px-2 py-1 rounded-full ${
                          item.status === "Pending"
                            ? "bg-yellow-100 text-yellow-700"
                            : item.status === "Approved"
                            ? "bg-green-100 text-green-700"
                            : item.status === "Rejected"
                            ? "bg-gray-300 text-gray-600"
                            : "bg-blue-100 text-blue-700"
                        }`}
                      >
                        {item.status}
                      </span>

                      <span
                        className={`text-xs px-2 py-1 rounded-full ${
                          item.priority === "High"
                            ? "bg-red-100 text-red-700"
                            : item.priority === "Medium"
                            ? "bg-orange-100 text-orange-700"
                            : "bg-blue-100 text-blue-700"
                        }`}
                      >
                        {item.priority}
                      </span>
                    </div>
                  </div>
                </div>

                <div className="text-sm text-gray-700 mb-2">{item.type}</div>
                <div className="text-xs text-slate-950 mb-2">Item: {item.order_details}</div>
                <div className="text-xs text-gray-400 mb-2">Requested: {item.requested}</div>
                <div className="text-sm mb-3">{item.description}</div>

                {/* Buttons: Approve/Reject (40% width) or Place on Calendar */}
                <div className="flex gap-2">
                  {item.status === "Pending" && (
                    <>
                      <button
                        onClick={() => handleApproveFromList(item.id)}
                        className="w-[40%] bg-green-600 hover:bg-green-700 text-white py-1 rounded-lg text-sm"
                      >
                        Approve
                      </button>
                      <button
                        onClick={() => handleRejectFromList(item.id)}
                        className="w-[40%] text-red-600 border border-red-700 hover:bg-red-100 py-1 rounded-lg text-sm"
                      >
                        Reject
                      </button>
                    </>
                  )}

                  {item.status === "Approved" && (
                    <button
                      onClick={() => openPlaceModal(item.id)}
                      className="w-[40%] text-blue-600 border border-blue-200 py-1 rounded-lg text-sm hover:bg-blue-50"
                    >
                      Place on Calendar
                    </button>
                  )}

                  {/* If Scheduled show small label */}
                  {item.status === "Scheduled" && (
                    <div className="ml-auto text-sm text-blue-700 bg-blue-50 px-2 py-1 rounded-full">Scheduled</div>
                  )}
                </div>
              </div>
            ))}
          </div>
        </div>

        {/* Right panel (calendar) */}
        <div className="flex-1 p-4">
          <div className="flex justify-between items-center mb-4">
            <h2 className="text-lg font-semibold flex items-center gap-2"><Calendar size={18} /> Production Calendar</h2>

            <select
              value={calendarView}
              onChange={(e) => {
                setCalendarView(e.target.value);
                const api = calendarRef.current?.getApi();
                api?.changeView(e.target.value);
              }}
              className="border rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
            >
              <option value="timeGridDay">Day</option>
              <option value="timeGridWeek">Week</option>
              <option value="dayGridMonth">Month</option>
            </select>
          </div>

          <div className="border rounded-xl p-4 bg-white shadow-sm">
            <FullCalendar
              ref={calendarRef}
              plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
              initialView={calendarView}
              headerToolbar={{
                left: "prev,next today",
                center: "title",
                right: "",
              }}
              droppable={true}
              editable={true}
              selectable={true}
              nowIndicator={true}
              events={events}
              drop={handleExternalDrop}
              eventClick={(ev) => {
                // simple event click: maybe show details or allow removal
                // optional: remove event
              }}
              height="80vh"
              slotMinTime="08:00:00"
              slotMaxTime="18:00:00"
              eventContent={(arg) => {
                // simple content - title only
                return (
                  <div style={{ padding: "2px 6px", color: "#fff" }}>
                    <div className="fc-event-title">{arg.event.title}</div>
                  </div>
                );
              }}
            />
          </div>
        </div>

        {/* Place on Calendar Modal (Headless UI Dialog) */}
        <Transition appear show={showPlaceModal} as={Fragment}>
          <Dialog as="div" className="fixed inset-0 z-40 overflow-y-auto" onClose={() => setShowPlaceModal(false)}>
            <div className="min-h-screen px-4 text-center">
              <Transition.Child
                as={Fragment}
                enter="ease-out duration-200"
                enterFrom="opacity-0"
                enterTo="opacity-100"
                leave="ease-in duration-150"
                leaveFrom="opacity-100"
                leaveTo="opacity-0"
              >
                <Dialog.Overlay className="fixed inset-0 bg-black/40" />
              </Transition.Child>

              {/* spacer to center */}
              <span className="inline-block h-screen align-middle" aria-hidden="true">&#8203;</span>

              <Transition.Child
                as={Fragment}
                enter="ease-out duration-200"
                enterFrom="opacity-0 scale-95"
                enterTo="opacity-100 scale-100"
                leave="ease-in duration-150"
                leaveFrom="opacity-100 scale-100"
                leaveTo="opacity-0 scale-95"
              >
                <div className="inline-block w-full max-w-2xl p-6 my-8 overflow-hidden text-left align-middle transition-all transform bg-white shadow-xl rounded-2xl">
                  <div className="flex justify-between items-start">
                    <Dialog.Title className="text-lg font-semibold">Schedule Urgent Case</Dialog.Title>
                    <button onClick={() => setShowPlaceModal(false)} className="text-gray-500 hover:text-gray-700">
                      <X />
                    </button>
                  </div>

                  <p className="text-sm text-gray-500 mt-2 mb-4">
                    Configure the scheduling details for urgent case {selectedCaseId}
                  </p>

                  {/* form grid */}
                  <div className="grid grid-cols-2 gap-4">
                    {/* Order ID (readonly) */}
                    <div>
                      <label className="text-sm text-gray-600">Order ID</label>
                      <input
                        type="text"
                        readOnly
                        value={placeForm.order}
                        className="mt-1 w-full rounded-md border px-3 py-2 bg-gray-50 text-sm"
                      />
                    </div>

                    {/* Thickness */}
                    <div>
                      <label className="text-sm text-gray-600">Thickness</label>
                      <select
                        value={placeForm.thickness}
                        onChange={(e) => setPlaceForm((p) => ({ ...p, thickness: e.target.value }))}
                        className="mt-1 w-full rounded-md border px-3 py-2 bg-white text-sm"
                      >
                        {thicknessOptions.map((t) => (
                          <option key={t} value={t}>{t}</option>
                        ))}
                      </select>
                    </div>

                    {/* Requested Delivery Date (readonly) */}
                    <div className="col-span-2">
                      <label className="text-sm text-gray-600">Requested Delivery Date</label>
                      <input
                        type="text"
                        readOnly
                        value={placeForm.requested}
                        className="mt-1 w-full rounded-md border px-3 py-2 bg-gray-50 text-sm"
                        placeholder="--"
                      />
                    </div>

                    {/* Proposed Furnace Slot -> handled by datetime-local */}
                    <div className="col-span-2">
                      <label className="text-sm text-gray-600">Proposed Furnace Slot (Date &amp; time)</label>
                      <input
                        type="datetime-local"
                        value={placeForm.datetime}
                        onChange={(e) => setPlaceForm((p) => ({ ...p, datetime: e.target.value }))}
                        className="mt-1 w-full rounded-md border px-3 py-2 bg-white text-sm"
                      />
                    </div>

                    {/* Priority */}
                    <div>
                      <label className="text-sm text-gray-600">Priority</label>
                      <select
                        value={placeForm.priority}
                        onChange={(e) => setPlaceForm((p) => ({ ...p, priority: e.target.value }))}
                        className="mt-1 w-full rounded-md border px-3 py-2 bg-white text-sm"
                      >
                        <option>Low</option>
                        <option>Medium</option>
                        <option>High</option>
                      </select>
                    </div>

                    {/* Notes */}
                    <div className="col-span-2">
                      <label className="text-sm text-gray-600">Notes</label>
                      <textarea
                        value={placeForm.notes}
                        onChange={(e) => setPlaceForm((p) => ({ ...p, notes: e.target.value }))}
                        className="mt-1 w-full rounded-md border px-3 py-2 bg-white text-sm"
                        rows={3}
                      />
                    </div>
                  </div>

                  {/* buttons */}
                  <div className="mt-6 flex justify-end gap-3">
                    <button
                      onClick={() => setShowPlaceModal(false)}
                      className="px-4 py-2 rounded-md border bg-white text-sm"
                    >
                      Cancel
                    </button>
                    <button
                      onClick={savePlaceAsPending}
                      className="px-4 py-2 rounded-md border bg-gray-50 text-sm"
                    >
                      Save as Pending
                    </button>
                    <button
                      onClick={approveAndPlace}
                      className="px-4 py-2 rounded-md bg-blue-600 text-white text-sm"
                    >
                      Approve & Place
                    </button>
                  </div>
                </div>
              </Transition.Child>
            </div>
          </Dialog>
        </Transition>

        {/* New Case Modal */}
        <Transition appear show={showNewModal} as={Fragment}>
          <Dialog as="div" className="fixed inset-0 z-40 overflow-y-auto" onClose={() => setShowNewModal(false)}>
            <div className="min-h-screen px-4 text-center">
              <Transition.Child
                as={Fragment}
                enter="ease-out duration-200"
                enterFrom="opacity-0"
                enterTo="opacity-100"
                leave="ease-in duration-150"
                leaveFrom="opacity-100"
                leaveTo="opacity-0"
              >
                <Dialog.Overlay className="fixed inset-0 bg-black/40" />
              </Transition.Child>

              <span className="inline-block h-screen align-middle" aria-hidden="true">&#8203;</span>

              <Transition.Child
                as={Fragment}
                enter="ease-out duration-200"
                enterFrom="opacity-0 scale-95"
                enterTo="opacity-100 scale-100"
                leave="ease-in duration-150"
                leaveFrom="opacity-100 scale-100"
                leaveTo="opacity-0 scale-95"
              >
                <div className="inline-block w-full max-w-xl p-6 my-8 overflow-hidden text-left align-middle transition-all transform bg-white shadow-xl rounded-2xl">
                  <div className="flex justify-between items-start">
                    <Dialog.Title className="text-lg font-semibold">New Urgent Case</Dialog.Title>
                    <button onClick={() => setShowNewModal(false)} className="text-gray-500 hover:text-gray-700">
                      <X />
                    </button>
                  </div>

                  <p className="text-sm text-gray-500 mt-2 mb-4">Create a new urgent case</p>

                  <div className="grid grid-cols-2 gap-4">
                    <div className="col-span-2">
                      <label className="text-sm text-gray-600">Case Name</label>
                      <input
                        type="text"
                        value={newForm.name}
                        onChange={(e) => setNewForm((p) => ({ ...p, name: e.target.value }))}
                        className="mt-1 w-full rounded-md border px-3 py-2 bg-white text-sm"
                        placeholder="e.g. UC-1028"
                      />
                    </div>

                    <div>
                      <label className="text-sm text-gray-600">Category</label>
                      <select
                        value={newForm.category}
                        onChange={(e) => setNewForm((p) => ({ ...p, category: e.target.value }))}
                        className="mt-1 w-full rounded-md border px-3 py-2 bg-white text-sm"
                      >
                        <option>FLSS</option>
                      </select>
                    </div>

                    <div>
                      <label className="text-sm text-gray-600">Priority</label>
                      <select
                        value={newForm.priority}
                        onChange={(e) => setNewForm((p) => ({ ...p, priority: e.target.value }))}
                        className="mt-1 w-full rounded-md border px-3 py-2 bg-white text-sm"
                      >
                        <option>Low</option>
                        <option>Medium</option>
                        <option>High</option>
                      </select>
                    </div>

                    <div className="col-span-2">
                      <label className="text-sm text-gray-600">Notes</label>
                      <textarea
                        value={newForm.notes}
                        onChange={(e) => setNewForm((p) => ({ ...p, notes: e.target.value }))}
                        className="mt-1 w-full rounded-md border px-3 py-2 bg-white text-sm"
                        rows={3}
                      />
                    </div>
                  </div>

                  <div className="mt-6 flex justify-end gap-3">
                    <button onClick={() => setShowNewModal(false)} className="px-4 py-2 rounded-md border bg-white text-sm">Cancel</button>
                    <button onClick={saveNewAsPending} className="px-4 py-2 rounded-md bg-blue-600 text-white text-sm">Save as Pending</button>
                  </div>
                </div>
              </Transition.Child>
            </div>
          </Dialog>
        </Transition>
      </div>  
    </div>
  );
}
