import { TrashIcon } from "@heroicons/react/outline";
import { Availability } from "@prisma/client";
import dayjs from "dayjs";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
import React, { useEffect, useState } from "react";
import TimezoneSelect, { ITimezoneOption } from "react-timezone-select";

import { useLocale } from "@lib/hooks/useLocale";

import Button from "@components/ui/Button";

import { WeekdaySelect } from "./WeekdaySelect";
import SetTimesModal from "./modal/SetTimesModal";

dayjs.extend(utc);
dayjs.extend(timezone);

type AvailabilityInput = Pick<Availability, "days" | "startTime" | "endTime">;

type Props = {
  timeZone: string;
  availability: Availability[];
  setTimeZone: (timeZone: string) => void;
  setAvailability: (schedule: {
    openingHours: AvailabilityInput[];
    dateOverrides: AvailabilityInput[];
  }) => void;
};

/**
 * @deprecated
 */
export const Scheduler = ({ availability, setAvailability, timeZone, setTimeZone }: Props) => {
  const { t, i18n } = useLocale();
  const [editSchedule, setEditSchedule] = useState(-1);
  const [openingHours, setOpeningHours] = useState<Availability[]>([]);

  useEffect(() => {
    setOpeningHours(availability.filter((item: Availability) => item.days.length !== 0));
  }, []);

  useEffect(() => {
    setAvailability({ openingHours, dateOverrides: [] });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [openingHours]);

  const addNewSchedule = () => setEditSchedule(openingHours.length);

  const applyEditSchedule = (changed: Availability) => {
    // new entry
    if (!changed.days) {
      changed.days = [1, 2, 3, 4, 5]; // Mon - Fri
      setOpeningHours(openingHours.concat(changed));
    } else {
      // update
      const replaceWith = { ...openingHours[editSchedule], ...changed };
      openingHours.splice(editSchedule, 1, replaceWith);
      setOpeningHours([...openingHours]);
    }
  };

  const removeScheduleAt = (toRemove: number) => {
    openingHours.splice(toRemove, 1);
    setOpeningHours([...openingHours]);
  };

  const OpeningHours = ({ idx, item }: { idx: number; item: Availability }) => (
    <li className="flex justify-between py-2 border-b">
      <div className="flex flex-col space-y-4 lg:inline-flex">
        <WeekdaySelect defaultValue={item.days} onSelect={(selected: number[]) => (item.days = selected)} />
        <button
          className="px-3 py-2 text-sm rounded-sm bg-neutral-100"
          type="button"
          onClick={() => setEditSchedule(idx)}>
          {item.startTime.toLocaleTimeString(i18n.language, { hour: "numeric", minute: "2-digit" })}
          &nbsp;{t("until")}&nbsp;
          {item.endTime.toLocaleTimeString(i18n.language, { hour: "numeric", minute: "2-digit" })}
        </button>
      </div>
      <button
        type="button"
        onClick={() => removeScheduleAt(idx)}
        className="px-2 py-1 ml-1 bg-transparent btn-sm">
        <TrashIcon className="inline w-5 h-5 -mt-1 text-gray-400" />
      </button>
    </li>
  );

  return (
    <div>
      <div className="flex">
        <div className="w-full">
          <div>
            <label htmlFor="timeZone" className="block text-sm font-medium text-gray-700">
              {t("timezone")}
            </label>
            <div className="mt-1">
              <TimezoneSelect
                id="timeZone"
                value={timeZone}
                onChange={(tz: ITimezoneOption) => setTimeZone(tz.value)}
                className="block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:ring-black focus:border-brand sm:text-sm"
              />
            </div>
          </div>
          <ul>
            {openingHours.map((item, idx) => (
              <OpeningHours key={idx} idx={idx} item={item} />
            ))}
          </ul>
          <Button type="button" onClick={addNewSchedule} className="mt-2" color="secondary" size="sm">
            {t("add_another")}
          </Button>
        </div>
      </div>
      {editSchedule >= 0 && (
        <SetTimesModal
          startTime={
            openingHours[editSchedule]
              ? new Date(openingHours[editSchedule].startTime).getHours() * 60 +
                new Date(openingHours[editSchedule].startTime).getMinutes()
              : 540
          }
          endTime={
            openingHours[editSchedule]
              ? new Date(openingHours[editSchedule].endTime).getHours() * 60 +
                new Date(openingHours[editSchedule].endTime).getMinutes()
              : 1020
          }
          onChange={(times: { startTime: number; endTime: number }) =>
            applyEditSchedule({
              ...(openingHours[editSchedule] || {}),
              startTime: new Date(
                new Date().setHours(Math.floor(times.startTime / 60), times.startTime % 60, 0, 0)
              ),
              endTime: new Date(
                new Date().setHours(Math.floor(times.endTime / 60), times.endTime % 60, 0, 0)
              ),
            })
          }
          onExit={() => setEditSchedule(-1)}
        />
      )}
    </div>
  );
};
