/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable react-hooks/exhaustive-deps */
import {
  add,
  addDays,
  eachDayOfInterval,
  endOfMonth,
  format,
  getISODay,
  isEqual,
  isWithinInterval,
  parse,
  startOfToday,
} from "date-fns";
import { enUS, ru } from "date-fns/locale";
import { useEffect, useState } from "react";
import ChevronRightIcon from "./icons/ChevronRightIcon";
import ChevronLeftIcon from "./icons/ChevronLeftIcon";
import { Trans } from "react-i18next";
import i18n from "../i18n";

interface CalendarProps {
  schedules: any[];
  handleSelect: (day: Date) => void;
  className?: string;
}

function classNames(...classes: (string | boolean)[]) {
  return classes.filter(Boolean).join(" ");
}

function Calendar({ schedules, handleSelect, className }: CalendarProps) {
  const today = startOfToday();
  const [selectedDay, setSelectedDay] = useState<Date | null>(null);
  const [currentMonth, setCurrentMonth] = useState(format(today, "MMM-yyyy"));
  const firstDayCurrentMonth = parse(currentMonth, "MMM-yyyy", new Date());

  const days = eachDayOfInterval({
    start: firstDayCurrentMonth,
    end: endOfMonth(firstDayCurrentMonth),
  });

  function previousMonth() {
    const firstDayNextMonth = add(firstDayCurrentMonth, { months: -1 });
    setCurrentMonth(format(firstDayNextMonth, "MMM-yyyy"));
  }

  function nextMonth() {
    const firstDayNextMonth = add(firstDayCurrentMonth, { months: 1 });
    setCurrentMonth(format(firstDayNextMonth, "MMM-yyyy"));
  }

  useEffect(() => {
    if (!selectedDay) return;

    handleSelect(selectedDay);
  }, [selectedDay]);

  return (
    <div className={`transition-opacity ${className}`}>
      <div className="flex items-center justify-between">
        <button onClick={previousMonth}>
          <ChevronLeftIcon />
        </button>

        <p className="text-sm text-white first-letter:uppercase w-fit">
          {format(
            firstDayCurrentMonth,
            "LLLL, yyyy",
            i18n.language === "ru" ? { locale: ru } : { locale: enUS }
          )}
        </p>

        <button onClick={nextMonth}>
          <ChevronRightIcon />
        </button>
      </div>
      <div className="sm:mt-8 mt-5 grid grid-cols-7 gap-2 font-gilroy text-sm text-center text-white font-semibold">
        <div>{i18n.language === "ru" ? "пн" : "Mo"}</div>
        <div>{i18n.language === "ru" ? "вт" : "Tu"}</div>
        <div>{i18n.language === "ru" ? "ср" : "We"}</div>
        <div>{i18n.language === "ru" ? "чт" : "Th"}</div>
        <div>{i18n.language === "ru" ? "пт" : "Fr"}</div>
        <div>{i18n.language === "ru" ? "сб" : "Sa"}</div>
        <div>{i18n.language === "ru" ? "вс" : "Su"}</div>
      </div>
      <div className="grid grid-cols-7 gap-2 mt-2 text-sm font-semibold">
        {days.map((day, dayIdx) => (
          <div
            key={day.toString()}
            className={classNames(
              dayIdx === 0 && colStartClasses[getISODay(day) - 1]
            )}
          >
            <button
              type="button"
              disabled={
                day < today ||
                schedules.some(
                  (schedule) =>
                    !isWithinInterval(day, {
                      start: new Date(schedule.startDate),
                      end: addDays(new Date(schedule.startDate), 13),
                    })
                )
              }
              onClick={() => setSelectedDay(day)}
              className={classNames(
                selectedDay !== null &&
                  isEqual(day, selectedDay) &&
                  "bg-[#798FFF] text-white hover:bg-opacity-100",
                "mx-auto flex min-w-[40px] h-10 items-center justify-center rounded-full transition-all text-[#798FFF] border border-[#798FFF] hover:bg-[#798FFF] hover:bg-opacity-20 disabled:text-[#3D425C] disabled:border-transparent disabled:hover:bg-transparent"
              )}
            >
              <time dateTime={format(day, "yyyy-MM-dd")}>
                {format(day, "d")}
              </time>
            </button>
          </div>
        ))}
      </div>
      <div className="mt-8 flex items-center gap-2">
        <div className="w-4 h-4 bg-[#798FFF] rounded"></div>
        <p className="text-[#798FFF]">
          - <Trans i18nKey={"sidebar.available"}>запись доступна</Trans>
        </p>
      </div>
    </div>
  );
}

const colStartClasses = [
  "",
  "col-start-2",
  "col-start-3",
  "col-start-4",
  "col-start-5",
  "col-start-6",
  "col-start-7",
];

export default Calendar;
