import axiosInstance from '../../src/axiosSecure';
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import { useRouter } from "next/router";
import DayOfWeek from "../DayOfWeek";
const common = require('src/helpers/common');
import { MobileTimePicker } from '@mui/x-date-pickers/MobileTimePicker';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFnsV3';
// import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';

import TextField from '@mui/material/TextField';
import bg from 'date-fns/locale/bg'; // Bulgarian locale


import { bgBG } from '../x-date-pickers/locales/bgBG'; // Your custom translation file
import { ToastContainer } from 'react-toastify';



const fetchConfig = async () => {
  const config = await import('../../config.json');
  return config.default;
};

/*
// ------------------ data model ------------------
model Availability {
  id                       Int              @id @default(autoincrement())
  publisher                Publisher        @relation(fields: [publisherId], references: [id], onDelete: Cascade)
  publisherId              String
  name                     String
  dayofweek                DayOfWeek
  dayOfMonth               Int?
  weekOfMonth              Int?
  startTime                DateTime
  endTime                  DateTime
  isActive                 Boolean          @default(true)
  type                     AvailabilityType @default(Weekly)
  isWithTransport          Boolean          @default(false)
  isFromPreviousAssignment Boolean          @default(false)
  isFromPreviousMonth      Boolean          @default(false)
  repeatWeekly             Boolean? // New field to indicate weekly repetition
  repeatFrequency          Int? // New field to indicate repetition frequency
  endDate                  DateTime? // New field for the end date of repetition

  @@map("Availability")
}


*/

//enum for abailability type - day of week or day of month; and array of values
const AvailabilityType = {
  WeeklyRecurrance: 'WeeklyRecurrance',
  ExactDate: 'ExactDate'
}
//const AvailabilityTypeValues = Object.values(AvailabilityType);



export default function AvailabilityForm({ publisherId, existingItem, inline, onDone, itemsForDay }) {

  const [availability, setAvailability] = useState(existingItem || {
    publisherId: publisherId || null,
    name: "Нов",
    dayofweek: "Monday",
    dayOfMonth: null,
    startTime: "08:00",
    endTime: "20:00",
    isActive: true,
    repeatWeekly: false,
    endDate: null,
  });
  const [items, setItems] = useState(itemsForDay || []); // [existingItem, ...items]

  const [selectedType, setSelectedOption] = useState(AvailabilityType.WeeklyRecurrance);
  const [isInline, setInline] = useState(inline || false);
  const [timeSlots, setTimeSlots] = useState([]);

  const [isMobile, setIsMobile] = useState(false);
  // Check screen width to determine if the device is mobile
  useEffect(() => {
    const handleResize = () => {
      setIsMobile(window.innerWidth < 768); // 768px is a common breakpoint for mobile devices
    };
    // Call the function to setAvailability the initial state
    handleResize();
    // Add event listener
    window.addEventListener('resize', handleResize);
    // Cleanup
    return () => window.removeEventListener('resize', handleResize);
  }, []);
  // Inside your component


  const [config, setConfig] = useState(null);
  useEffect(() => {
    fetchConfig().then(config => {
      // Use config here to adjust form fields
      console.log("UI config: ", config);
      setConfig(config);
    });
  }, []);

  const [dataFetched, setDataFetched] = useState(false);

  const router = useRouter();
  const initialId = existingItem?.id || router.query.id;

  const urls = {
    apiUrl: "/api/data/availabilities/",
    indexUrl: "/cart/availabilities"
  };

  // Define the minimum and maximum times
  const minTime = new Date();
  minTime.setHours(8, 0, 0, 0); // 8:00 AM
  const maxTime = new Date();
  maxTime.setHours(20, 0, 0, 0); // 8:00 PM


  //always setAvailability publisherId
  useEffect(() => {
    availability.publisherId = publisherId;
    console.log("availability.publisherId: ", availability.publisherId);
  }, [availability]);



  if (typeof window !== 'undefined') {
    useEffect(() => {
      // If component is not in inline mode and there's no existing availability, fetch the availability based on the query ID
      // Fetch availability from DB only if it's not fetched yet, and there's no existing availability
      if (!isInline && !existingItem && !dataFetched && router.query.id) {
        fetchItemFromDB(parseInt(router.query.id.toString()));
        setDataFetched(true); // Set data as fetched
      }
    }, [router.query.id, isInline, existingItem, dataFetched]);
  }

  // const [isEdit, setIsEdit] = useState(false);
  const fetchItemFromDB = async (id) => {
    try {
      console.log("fetching availability " + id);
      const { data } = await axiosInstance.get(urls.apiUrl + id);
      data.startTime = formatTime(data.startTime);
      data.endTime = formatTime(data.endTime);
      setAvailability(data);
      console.log(data);
    } catch (error) {
      console.error(error);
    }
  };

  const handleChange = ({ target }) => {
    // const { name, value } = e.target;
    // setItem((prev) => ({ ...prev, [name]: value }));
    console.log("AvailabilityForm: handleChange: " + target.name + " = " + target.value);
    setAvailability({ ...availability, [target.name]: target.value });
  }

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {

      if (!availability.name) {
        // availability.name = "От календара";
        availability.name = common.getTimeFormatted(availability.startTime) + "-" + common.getTimeFormatted(availability.endTime);
      }

      availability.dayofweek = common.getDayOfWeekNameEnEnumForDate(availability.startTime);
      if (availability.repeatWeekly) {
        availability.dayOfMonth = null;
        availability.weekOfMonth = 0; //weekly recurrance - no need for week of month. special value 0
      } else {
        availability.endDate = null;
        availability.dayOfMonth = availability.startTime.getDate();
      }

      delete availability.date; //remove date from availability as it is not part of the db model. we store the info in startDate and endDate
      // ---------------------- CB UI --------------
      if (config.checkboxUI.enabled) {
        const selectedSlots = timeSlots.filter(slot => slot.isChecked);
        // Sort the selected intervals by start time
        const sortedSlots = [...selectedSlots].sort((a, b) => a.startTime - b.startTime);

        // Group continuous slots
        const groupedIntervals = [];
        let currentGroup = [sortedSlots[0]];

        for (let i = 1; i < sortedSlots.length; i++) {
          const previousSlot = currentGroup[currentGroup.length - 1];
          const currentSlot = sortedSlots[i];
          // Calculate the difference in hours between slots
          const difference = (currentSlot.startTime - previousSlot.endTime) / (60 * 60 * 1000);

          // Assuming each slot represents an exact match to the increment (1.5 hours), we group them
          if (difference === 0) {
            currentGroup.push(currentSlot);
          } else {
            groupedIntervals.push(currentGroup);
            currentGroup = [currentSlot];
          }
        }
        // Don't forget the last group
        if (currentGroup.length > 0) {
          groupedIntervals.push(currentGroup);
        }

        // Create availability objects from grouped slots
        const availabilities = groupedIntervals.map(group => {
          const startTime = group[0].startTime;
          const endTime = group[group.length - 1].endTime;
          return {
            publisherId: availability.publisherId,
            startTime: startTime,
            endTime: endTime,
            isWithTransportIn: group[0].isFirst && timeSlots[0].isWithTransport,
            isWithTransportOut: group[group.length - 1].isLast && timeSlots[timeSlots.length - 1].isWithTransport,
            // Add other necessary fields, like isWithTransport if applicable
          };
        });

        //if more than one interval, we delete and recreate the availability, as it is not possble to map them
        if (availability.id && availabilities.length > 1) {
          await axiosInstance.delete(urls.apiUrl + availability.id);
          delete availability.id;
        }

        // const firstSlotWithTransport = timeSlots[0].checked && timeSlots[0]?.isWithTransport;
        // const lastSlotWithTransport = timeSlots[timeSlots.length - 1].checked && timeSlots[timeSlots.length - 1]?.isWithTransport;

        availabilities.forEach(async av => {
          // expand availability
          const avToStore = {
            ...availability,
            ...av,
            startTime: av.startTime,
            endTime: av.endTime,
            name: "От календара",
            id: undefined,

            // isWithTransportIn: firstSlotWithTransport,
            // isWithTransportOut: lastSlotWithTransport,

          };
          console.log("AvailabilityForm: handleSubmit: " + av);
          if (availability.id) {
            // UPDATE EXISTING ITEM
            await axiosInstance.put(urls.apiUrl + availability.id, {
              ...avToStore,
            });
          } else {
            // CREATE NEW ITEM
            await axiosInstance.post(urls.apiUrl, avToStore);
          }
          handleCompletion(avToStore); // Assuming `handleCompletion` is defined to handle post-save logic
        });



      }
      // ---------------------- TimePicker UI --------------
      else {
        availability.publisher = { connect: { id: availability.publisherId } };
        delete availability.publisherId;

        if (availability.id) {
          console.log('editing avail# ' + availability.id);
          //delete availability.id;

          // UPDATE EXISTING ITEM
          var itemUpdate = { ...availability, id: undefined };
          await axiosInstance.put(urls.apiUrl + availability.id, {
            ...itemUpdate,
          });
          toast.success("Task Updated", {
            position: "bottom-center",
          });
        } else {
          // CREATE NEW ITEM
          console.log('creating new  avail: ' + availability);
          const response = await axiosInstance.post(urls.apiUrl, availability);
          const createdItem = response.data;
          availability.id = createdItem.id;
          toast.success("Task Saved", {
            position: "bottom-center",
          });
        }
      }

      handleCompletion(availability);
    } catch (error) {
      alert("Нещо се обърка. Моля, опитайте отново по-късно.");
      toast.error("Нещо се обърка. Моля, опитайте отново по-късно.");
      console.error(error.message);
    }
  };

  const handleDelete = async (e) => {
    e.preventDefault();
    try {
      if (availability.id) {
        // console.log("deleting publisher id = ", router.query.id, "; url=" + urls.apiUrl + router.query.id);
        await axiosInstance.delete(urls.apiUrl + availability.id);
        toast.success("Записът изтрит", {
          position: "bottom-center",
        });
        handleCompletion({ deleted: true }); // Assuming handleCompletion is defined and properly handles post-deletion logic
      }
    } catch (error) {
      alert("Нещо се обърка при изтриването. Моля, опитайте отново или се свържете с нас");
      console.log(JSON.stringify(error));
      toast.error(error.response?.data?.message || "An error occurred");
    }
  };

  const handleCompletion = async (result) => {
    console.log("AvailabilityForm: handleCompletion");
    if (isInline) {
      if (onDone) {
        onDone(result);
      }
    } else {
      router.push(urls.indexUrl);
    }
  }

  console.log("AvailabilityForm: publisherId: " + availability.publisherId + ", id: " + availability.id, ", inline: " + isInline);


  const generateTimeSlots = (start, end, increment, item) => {
    const slots = [];
    // Ensure we're working with the correct date base
    const baseDate = new Date(item?.startTime || new Date());
    baseDate.setHours(start, 0, 0, 0); // Set start time on the base date
    let currentTime = baseDate.getTime();

    const endDate = new Date(item?.startTime || new Date());
    endDate.setHours(end, 0, 0, 0); // Set end time on the same date
    const endTime = endDate.getTime();

    // Parse availability's startTime and endTime into Date objects for comparison
    const itemStartDate = new Date(item?.startTime);
    const itemEndDate = new Date(item?.endTime);


    while (currentTime < endTime) {
      let slotStart = new Date(currentTime);
      let slotEnd = new Date(currentTime + increment * 60 * 60 * 1000); // Calculate slot end time

      // Check if the slot overlaps with the availability's time range
      const isChecked = slotStart < itemEndDate && slotEnd > itemStartDate;

      slots.push({
        startTime: slotStart,
        endTime: slotEnd,
        isChecked: isChecked,
      });
      currentTime += increment * 60 * 60 * 1000; // Move to the next slot
    }
    slots[0].isFirst = true;
    slots[slots.length - 1].isLast = true;
    slots[0].isWithTransport = item.isWithTransportIn;
    slots[slots.length - 1].isWithTransport = item.isWithTransportOut;


    return slots;
  };


  const TimeSlotCheckboxes = ({ slots, setSlots, item }) => {
    const [allDay, setAllDay] = useState(false);

    const handleAllDayChange = (e) => {
      const updatedSlots = slots.map(slot => ({
        ...slot,
        isChecked: e.target.checked,
      }));
      setSlots(updatedSlots);
      setAllDay(e.target.checked)
      console.log("handleAllDayChange: allDay: " + allDay + ", updatedSlots: " + JSON.stringify(updatedSlots));
    };
    useEffect(() => {
      console.log("allDay updated to: ", allDay);
      const updatedSlots = slots.map(slot => ({
        ...slot,
        isChecked: allDay
      }));
      //setSlots(updatedSlots);
    }, [allDay]);

    const handleSlotCheckedChange = (changedSlot) => {
      const updatedSlots = slots.map(slot => {
        if (slot.startTime === changedSlot.startTime && slot.endTime === changedSlot.endTime) {
          return { ...slot, isChecked: !slot.isChecked };
        }
        return slot;
      });
      // If slot is either first or last and it's being unchecked, also uncheck and disable transport
      if ((changedSlot.isFirst || changedSlot.isLast) && !changedSlot.isChecked) {
        changedSlot.isWithTransport = false;
      }
      setSlots(updatedSlots);
    };

    const handleTransportChange = (changedSlot) => {
      const updatedSlots = slots.map(slot => {
        if (slot.startTime === changedSlot.startTime && slot.endTime === changedSlot.endTime) {
          return { ...slot, isWithTransport: !slot.isWithTransport };
        }
        return slot;
      });
      setSlots(updatedSlots);
    };


    return (
      <>
        <label className="checkbox-container flex items-center mb-2">
          <input type="checkbox" checked={allDay} onChange={e => handleAllDayChange(e)} className="form-checkbox h-5 w-5 text-gray-600 mx-2" />
          Цял ден
          <span className="checkmark"></span>
        </label>
        {slots.map((slot, index) => {
          const slotLabel = `${slot.startTime.getHours()}:${slot.startTime.getMinutes() === 0 ? '00' : slot.startTime.getMinutes()} до ${slot.endTime.getHours()}:${slot.endTime.getMinutes() === 0 ? '00' : slot.endTime.getMinutes()}`;
          slot.transportNeeded = slot.isFirst || slot.isLast;
          // Determine if the current slot is the first or the last

          return (
            <div key={index} className="mb-1 flex justify-between items-center">
              <label className={`checkbox-container flex items-center mb-2 ${allDay ? 'opacity-50' : ''}`}>
                <input type="checkbox" checked={slot.isChecked || allDay} onChange={() => handleSlotCheckedChange(slot)}
                  disabled={allDay}
                  className="form-checkbox h-5 w-5 text-gray-600 mx-2" />
                {slotLabel}
                <span className="checkmark"></span>
              </label>

              {/* Conditionally render transport checkbox based on slot being first or last */}
              {slot.transportNeeded && (
                <label className={`checkbox-container flex items-center ${(!slot.isChecked || allDay) ? 'opacity-50' : ''}`}>
                  <input type="checkbox"
                    className="form-checkbox h-5 w-5 text-gray-600 mx-2"
                    checked={slot.isWithTransport}
                    disabled={!slot.isChecked || allDay}
                    onChange={() => handleTransportChange(slot)} />
                  {slot.isFirst ? 'Вземане' : 'Връщане'}
                  <span className="checkmark"></span>
                </label>
              )}
            </div>
          );
        })}
      </>
    );
  };

  useEffect(() => {
    setTimeSlots(generateTimeSlots(9, 18, 1.5, availability));
  }, []);

  return (
    <div style={{ width: isMobile ? '90%' : 'max-w-xs', margin: '0 auto' }} >
      <ToastContainer></ToastContainer>
      <form id="formAv" className="form p-5 bg-white shadow-md rounded-lg p-8 pr-12" onSubmit={handleSubmit}>
        <h3 className="text-xl font-semibold mb-5 text-gray-800 border-b pb-2">
          {availability.id ? "Редактирай" : "Създай"} Достъпност
        </h3>

        <LocalizationProvider dateAdapter={AdapterDateFns} localeText={bgBG} adapterLocale={bg}>
          <div className="mb-2">
            <DatePicker label="Изберете дата" value={availability.startTime} onChange={(value) => setAvailability({ ...availability, endTime: value })} />
          </div>

          <div>
            {config?.checkboxUI && config.checkboxUI.enabled ? (
              <div className="mb-1">
                {/* Time slot checkboxes */}
                <TimeSlotCheckboxes slots={timeSlots} setSlots={setTimeSlots} item={availability} />
              </div>
            ) : (
              <>
                {/* Start Time Picker */}
                <div className="mb-2">
                  <MobileTimePicker label="От" minutesStep={15} value={availability.startTime} minTime={minTime} maxTime={maxTime}
                    onChange={(value) => setAvailability({ ...availability, startTime: value })} />
                </div>

                {/* End Time Picker */}
                <div className="mb-2">
                  <MobileTimePicker label="До" minutesStep={15} value={availability.endTime} minTime={minTime} maxTime={maxTime}
                    onChange={(value) => setAvailability({ ...availability, endTime: value })} />
                </div>
                <div className="mb-2">
                  <label className="checkbox-container">
                    <input type="checkbox" checked={availability.isWithTransport} className="form-checkbox h-5 w-5 text-gray-600 mx-2"
                      onChange={() => setAvailability({ ...availability, isWithTransport: !availability.isWithTransport })} />
                    мога да взема/върна количките
                    <span className="checkmark"></span>
                  </label>
                </div>
              </>
            )}
          </div>


          <div className="mb-2">
            <label className="checkbox-container">
              <input type="checkbox" checked={availability.repeatWeekly} className="form-checkbox h-5 w-5 text-gray-600 mx-2"
                onChange={() => setAvailability({ ...availability, repeatWeekly: !availability.repeatWeekly })} />
              Повтаряй всяка {' '}
              {/* {availability.repeatWeekly && (
                <select
                  style={{
                    appearance: 'none',
                    MozAppearance: 'none',
                    WebkitAppearance: 'none',
                    border: 'black solid 1px',
                    background: 'transparent',
                    padding: '0 4px',
                    margin: '0 2px',
                    height: 'auto',
                    fontSize: '16px', // Adjust to match surrounding text
                    textAlign: 'center',
                    color: 'inherit',
                  }}
                  // className="appearance-none border border-black bg-transparent px-1 py-0 mx-0 mr-1 h-auto text-base text-center text-current  align-middle cursor-pointer"

                  //className="form-select mx-2 h-8 text-gray-600"
                  value={availability.repeatFrequency || 1}
                  onChange={(e) => setAvailability({ ...availability, repeatFrequency: parseInt(e.target.value, 10) })}
                >
                  <option value="1">1</option>
                  <option value="2">2</option>
                  <option value="3">3</option>
                  <option value="4">4</option>
                </select>
              )} */}
              седмица
              <span className="checkmark"></span>
            </label>
          </div>

          {false && availability.repeatWeekly && (

            <div className="mb-2">
              <DatePicker label="До" value={availability.endDate} onChange={(value) => setAvailability({ ...availability, endDate: value })} />
            </div>
          )}
        </LocalizationProvider>

        <div className="mb-2 hidden">
          <div className="form-check">
            <input className="checkbox form-input" type="checkbox" id="isActive" name="isActive" onChange={handleChange} checked={availability.isActive} autoComplete="off" />
            <label className="label" htmlFor="isActive">активно</label>
          </div>
        </div>
        {/* <input type="hidden" name="isActive" value={availability.isActive} /> */}

        <div className="panel-actions">
          <button className="action-button" onClick={() => handleCompletion()}> Отмени </button>
          {availability.id && (
            <><button className="button bg-red-500 hover:bg-red-700 focus:outline-none focus:shadow-outline" type="button" onClick={handleDelete}>
              Изтрий
            </button></>
          )}
          <button
            className="button bg-blue-500 hover:bg-blue-700 focus:outline-none focus:shadow-outline"
          > {availability.id ? "Обнови" : "Запиши"}
          </button>
        </div>
      </form>
    </div>

  );
}

