"use client";

import { useState } from "react";
import axiosInstance from "@/lib/axiosInstance";
import { fmt12, toMinutes, toHHMM } from "@/lib/timeslot-utils";
import { SLOT_DURATION_MINUTES } from "@/lib/timeslot-constants";
import Link from "next/link";

interface TimeSlot {
  id: number;
  slot_date: string;
  start_time: string;
  end_time: string;
  capacity: number;
  booked_count: number;
  is_override: boolean;
}

function to12Parts(value: string): { hour: number; minute: number; period: "AM" | "PM" } {
  const [hStr, mStr] = value ? value.split(":") : ["09", "00"];
  let h = parseInt(hStr, 10);
  const m = parseInt(mStr, 10) || 0;
  const period: "AM" | "PM" = h >= 12 ? "PM" : "AM";
  h = h % 12;
  if (h === 0) h = 12;
  return { hour: h, minute: m, period };
}

function to24(hour: number, minute: number, period: "AM" | "PM") {
  let h = hour % 12;
  if (period === "PM") h += 12;
  return `${String(h).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
}

export default function EditDateSlotsPage() {
  const [date, setDate] = useState("");
  const [slots, setSlots] = useState<TimeSlot[]>([]);
  const [loading, setLoading] = useState(false);
  const [hasLoaded, setHasLoaded] = useState(false); // true only after a real API response for the current date
  const [newStartTime, setNewStartTime] = useState("09:00");
  const [addError, setAddError] = useState<string | null>(null);
  const [adding, setAdding] = useState(false);
  const today = new Date().toISOString().split("T")[0];

  const { hour: newHour, minute: newMinute, period: newPeriod } = to12Parts(newStartTime);

  const hourOptions = Array.from({ length: 12 }, (_, i) => i + 1);
  const minuteOptions = Array.from({ length: 12 }, (_, i) => i * 5); // 5-min steps

  const handleHourChange = (h: number) => setNewStartTime(to24(h, newMinute, newPeriod));
  const handleMinuteChange = (m: number) => setNewStartTime(to24(newHour, m, newPeriod));
  const handlePeriodChange = (p: "AM" | "PM") => setNewStartTime(to24(newHour, newMinute, p));

  const loadSlots = async () => {
    if (!date) return;
    setLoading(true);
    setAddError(null);
    setHasLoaded(false);
    try {
      const { data } = await axiosInstance.get(`/admin/timeslots?date=${date}`);
      setSlots(data.data.sort((a: TimeSlot, b: TimeSlot) => a.start_time.localeCompare(b.start_time)));
      setHasLoaded(true);
    } finally {
      setLoading(false);
    }
  };

  // Picking a new date invalidates whatever was loaded for the previous date,
  // so the "no slots" / add-slot UI can't show stale results from before Load was clicked
  const handleDateChange = (value: string) => {
    setDate(value);
    setSlots([]);
    setHasLoaded(false);
    setAddError(null);
  };

  const deleteSlot = async (id: number) => {
    await axiosInstance.delete(`/admin/timeslots/${id}`);
    setSlots((prev) => prev.filter((s) => s.id !== id));
  };

  // Client-side check first, so the admin gets instant feedback before hitting the API.
  // The server still re-validates this — this is just to avoid a round trip on obvious overlaps.
  const wouldOverlap = (startTime: string) => {
    const newStart = toMinutes(startTime);
    const newEnd = newStart + SLOT_DURATION_MINUTES;
    return slots.some((s) => {
      const existingStart = toMinutes(s.start_time);
      const existingEnd = toMinutes(s.end_time);
      return newStart < existingEnd && newEnd > existingStart;
    });
  };

  const addSlot = async () => {
    setAddError(null);
    if (wouldOverlap(newStartTime)) {
      setAddError("This time overlaps with an existing slot on this date.");
      return;
    }
    setAdding(true);
    try {
      const { data } = await axiosInstance.post("/admin/timeslots", {
        slot_date: date,
        start_time: newStartTime,
      });
      setSlots((prev) => [...prev, data.data].sort((a, b) => a.start_time.localeCompare(b.start_time)));
    } catch (err: any) {
      setAddError(err?.response?.data?.error ?? "Failed to add slot.");
    } finally {
      setAdding(false);
    }
  };

  return (
    <div className="admin-page-wrapper">

      <div className="admin-page-header mb-4">
        <div className="d-flex justify-content-between align-items-center">
          <div>
            <h2 className="admin-page-title">Edit slots for a date</h2>
            <p className="admin-page-subtitle">Manage all slots for a specific date here</p>
          </div>
          <div className="d-flex gap-2 flex-wrap">
            <Link href="/admin/timeslots" className="btn btn-light px-4">
              <i className="bi bi-arrow-left me-2" />
              Back to Time Slots
            </Link>
            <Link href="/admin/schedule/create" className="admin-theme-btn">
              <i className="bi bi-calendar-check"></i> Slot Assignment
            </Link>
          </div>
        </div>
      </div>

      <div className="card-theme p-3 p-sm-3 p-md-4">
        <div className="row">
          <div className="col-12">
            <div className="d-flex gap-2 align-items-end mb-3">
              <div>
                <label className="form-label">Date</label>
                <input type="date" className="form-control" value={date} onChange={(e) => handleDateChange(e.target.value)} min={today} />
              </div>
              <button className="admin-theme-btn" onClick={loadSlots} disabled={loading || !date}>
                {loading ? "Loading..." : "Load slots"}
              </button>
            </div>
          </div>

          {/* Only render anything below once a load has actually completed for the current date */}
          {hasLoaded && !loading && (
            <>
              {slots.length === 0 && (
                <p className="text-muted small mb-0">No slots for this date yet.</p>
              )}
              <div className="col-12">
                <div className="row gx-2">
                  {slots.map((slot) => (
                    <div key={slot.id} className="col-xl-2 col-xl-2 col-lg-3 col-md-3 col-sm-4 col-6 mb-2">
                      <div className="d-flex flex-column align-items-center editslotbx h-100">
                        <div className="w-100">
                          <h4>
                            {fmt12(slot.start_time)} - {fmt12(slot.end_time)}
                          </h4>
                          <p>{slot.booked_count} assigned</p>
                          {slot.is_override && (
                            <span
                              className="badge"
                              style={{
                                backgroundColor: "#f9cb6c",
                                color: "#000",
                              }}
                            >
                              Manually Added
                            </span>
                          )}
                        </div>
                        <button
                          className="remove-btn"
                          disabled={slot.booked_count > 0}
                          title={
                            slot.booked_count > 0
                              ? "Can't delete a slot with students assigned"
                              : "Delete slot"
                          }
                          onClick={() => deleteSlot(slot.id)}
                        >
                          <i className="bi bi-x"></i>
                        </button>
                      </div>
                    </div>
                  ))}
                </div>
              </div>

              <div className="col-12">
                <div className="border rounded p-3">
                  <p className="fw-medium small mb-2">Add a new slot for this date</p>
                  <div className="d-flex align-items-center gap-2 flex-wrap">
                    <div className="d-flex align-items-center gap-1">
                      <select
                        className="form-select form-select-sm"
                        style={{ width: 70 }}
                        value={newHour}
                        onChange={(e) => handleHourChange(parseInt(e.target.value, 10))}
                      >
                        {hourOptions.map((h) => (
                          <option key={h} value={h}>
                            {String(h).padStart(2, "0")}
                          </option>
                        ))}
                      </select>
                      <span>:</span>
                      <select
                        className="form-select form-select-sm"
                        style={{ width: 70 }}
                        value={newMinute}
                        onChange={(e) => handleMinuteChange(parseInt(e.target.value, 10))}
                      >
                        {minuteOptions.map((m) => (
                          <option key={m} value={m}>
                            {String(m).padStart(2, "0")}
                          </option>
                        ))}
                      </select>
                      <select
                        className="form-select form-select-sm"
                        style={{ width: 75 }}
                        value={newPeriod}
                        onChange={(e) => handlePeriodChange(e.target.value as "AM" | "PM")}
                      >
                        <option value="AM">AM</option>
                        <option value="PM">PM</option>
                      </select>
                    </div>
                    <span className="text-muted small">
                      ends at {fmt12(toHHMM(toMinutes(newStartTime) + SLOT_DURATION_MINUTES))} ({SLOT_DURATION_MINUTES / 60} hr slot)
                    </span>
                    <button className="admin-theme-btn" onClick={addSlot} disabled={adding}>
                      {adding ? "Adding..." : "Add slot"}
                    </button>
                  </div>
                  {addError && <p className="text-danger small mt-2 mb-0">{addError}</p>}
                </div>
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
}