import React, { useState, useRef, useEffect } from "react";
import {THRESH_HOLD} from "../../utils/constants"

const TimePicker = ({ label, onChange, interval = 10, value,checkInTime,checkOutTime }) => {
  const [time, setTime] = useState(value || "");
  const [isOpen, setIsOpen] = useState(false);
  const dropdownRef = useRef(null);
  const slotRefs = useRef({});

  const getCurrentTime = () => {
    const now = new Date();
    const minutes = now.getMinutes();
    const roundedMinutes = Math.round(minutes / interval) * interval;
    now.setMinutes(roundedMinutes);
    now.setSeconds(0);
    now.setMilliseconds(0);
    return now;
  };

  const formatTime = (date) => {
    let hours = date.getHours();
    const minutes = date.getMinutes();
    const period = hours >= 12 ? "PM" : "AM";

    hours = hours % 12; // Convert 24-hour format to 12-hour format
    hours = hours ? hours : 12; // The hour '0' should be '12'
    const hoursFormatted = hours < 10 ? `0${hours}` : hours; // Ensure two-digit hour
    const minutesFormatted = minutes < 10 ? `0${minutes}` : minutes; // Ensure two-digit minutes

    return `${hoursFormatted}:${minutesFormatted} ${period}`;
  };

  const generateTimeSlots = () => {
    const slots = [];
    const now = new Date();
    const currentSlot = new Date();
    currentSlot.setMinutes(
      Math.floor(currentSlot.getMinutes() / interval) * interval
    );
    currentSlot.setSeconds(0);
    currentSlot.setMilliseconds(0);

    const checkInDate = checkInTime ? new Date(checkInTime) : null;

    const checkOutDate = checkOutTime ? new Date(checkOutTime) : null;
  
    const dayStart = new Date();
    const dayEnd = new Date();
    if (checkInDate) {
      dayStart.setTime(checkInDate.getTime());
      dayEnd.setTime(checkInDate.getTime());
    }
    dayStart.setHours(0, 0, 0, 0);
    dayEnd.setHours(23, 59, 59, 999);
  
    let minSelectable = null;
    let maxSelectable = null;
  
    // Activity 0: Time slots based on current time
    if (!checkInDate) {
      // Case 1: No check-in time (new check-in)
      minSelectable = new Date(dayStart);
      maxSelectable = new Date(currentSlot);
    }
    // Activity 1: Time slots based on check-in time today
   else if (checkInDate && !checkOutDate) {
    const hoursDiff = (now - checkInDate) / (1000 * 60 * 60);
    if (hoursDiff < THRESH_HOLD) {
      // Case 2: Check-in present, no checkout, within THRESH_HOLD hours
        minSelectable = new Date(checkInDate);
        maxSelectable = new Date(currentSlot);
      } else {
        // Case 4: Check-in present, no checkout, more than THRESH_HOLD hours
        minSelectable = new Date(checkInDate);
        maxSelectable = new Date(dayEnd);
      }
    } else if (checkInDate && checkOutDate) {
      // Case 3: Both check-in and checkout present
      const isSameDay = new Date(checkOutDate).toDateString() === new Date().toDateString();
      minSelectable = new Date(checkOutDate);
      maxSelectable = isSameDay ? new Date(dayEnd) : new Date(currentSlot);
    }
  
    const slot = new Date(dayStart.getTime());
    while (slot <= dayEnd) {
      const formatted = formatTime(slot);

      const isSelectable = slot >= minSelectable && slot <= maxSelectable;
      slots.push({ time: formatted, isSelectable });

      slot.setMinutes(slot.getMinutes() + interval);
    }

    return slots;
  };

  const handleSelect = (selectedTime) => {
    setTime(selectedTime);
    if (onChange) onChange(selectedTime);
    setIsOpen(false);
  };

  useEffect(() => {
    const handleClickOutside = (event) => {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
        setIsOpen(false);
      }
    };
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);


  useEffect(() => {
    if (!value) {
      const defaultTime = formatTime(getCurrentTime());
      setTime(defaultTime);
      if (onChange) onChange(defaultTime);
    }
  }, [value, interval, onChange]);


  useEffect(() => {
    if (isOpen && time && slotRefs.current[time]) {
      const selectedSlot = slotRefs.current[time];
      selectedSlot.scrollIntoView({
        behavior: "smooth",
        block: "center",
      });
    }
  }, [isOpen, time]);


  return (
    <div className="position-relative w-100" ref={dropdownRef}>
      {label && <label className="form-label">{label}</label>}
      <div className="position-relative">
        <input
          type="text"
          className="form-control pe-5"
          value={time}
          readOnly
          onClick={() => setIsOpen(!isOpen)}
          style={{ cursor: "pointer" }}
        />
        <span
          className="position-absolute end-0 top-50 translate-middle-y pe-3 d-flex align-items-center"
          style={{ cursor: "pointer" }}
          onClick={() => setIsOpen(!isOpen)}
        >
          <i className="bx bx-time fs-4"></i>
        </span>
      </div>

      {isOpen && (
        <div
          className="dropdown-menu show shadow-lg border rounded p-2"
          style={{
            position: "absolute",
            width: "auto",
            background: "#fff",
            display: "flex",
            flexDirection: "column",
            gap: "5px",
            maxHeight: "200px",
            overflowY: "auto",
          }}
        >
          {generateTimeSlots().map(({ time: slotTime, isSelectable }, index) => (
            <button
              key={index}
              className={`dropdown-item px-3 py-1 text-center rounded-1 ${
                time === slotTime ? "btn-primary" : ""
              }`}
              ref={(el) => (slotRefs.current[slotTime] = el)}
              onClick={(event) => {
                event.preventDefault();
                if (isSelectable) handleSelect(slotTime);
              }}
              disabled={!isSelectable}
              style={
                !isSelectable ? { opacity: 0.5, cursor: "not-allowed" } : {}
              }
            >
              {slotTime}
            </button>
          ))}
        </div>
      )}
    </div>
  );
};

export default TimePicker;