import { useEffect, useState } from 'react';

import dayjs from 'dayjs';
import 'dayjs/locale/ru';

import { Button } from '@/components/buttons';
import CalendarDaysGrid from '@/components/calendar/components/CalendarDaysGrid';
import CalendarFooter from '@/components/calendar/components/CalendarFooter';
import CalendarHead from '@/components/calendar/components/CalendarHead';
import CalendarWeekDayLabels from '@/components/calendar/components/CalendarWeekDayLabels';
import { TimeInput } from '@/components/inputs/components/time-input/TimeInput';
import { classNames } from '@/utils/classNames';

export type TCalendarComponentProps = {
  locale: 'en' | 'ru';
  calendarDate?: Date | string;
  setISOString: (dateTime: string) => void;
  allowPastDates?: boolean;
};

export function Calendar({
  setISOString,
  calendarDate,
  locale,
  allowPastDates,
}: TCalendarComponentProps): React.ReactElement {
  dayjs.locale(locale);
  const [currentMonthDate, setCurrentMonthDate] = useState(dayjs());
  const [currentDate, setCurrentDate] = useState(dayjs());
  const [currentTime, setCurrentTime] = useState('');
  const isToday = dayjs(currentDate).isSame(dayjs(), 'day');
  const dayClasses = 'grid grid-cols-7 justify-between items-center';

  const getUserTimezone = () => {
    const userTimezone = Math.abs(new Date().getTimezoneOffset() / 60);
    const formattedUserTimeZone = userTimezone >= 10 ? userTimezone : `0${userTimezone}`;

    return userTimezone > 0 ? `+${formattedUserTimeZone}` : `-${formattedUserTimeZone}`;
  };

  const getAssembledISOString = () => {
    if (!currentTime) {
      return;
    }

    return `${currentDate.format('YYYY-MM-DD')}T${currentTime}:00.000${getUserTimezone()}:00`;
  };

  const apply = () => {
    const assembledIsoString = getAssembledISOString();

    if (!assembledIsoString) {
      return;
    }

    setISOString(assembledIsoString);
  };

  useEffect(() => {
    if (calendarDate) {
      const dateTime = dayjs(calendarDate);
      const time = dateTime.format('HH:mm');

      setCurrentDate(dateTime);
      setCurrentMonthDate(dateTime);
      setCurrentTime(time);
    }
  }, [calendarDate]);

  return (
    <div className="w-[352px] flex flex-col border-1 border-solid border-gray-ui-700 rounded-lg">
      <CalendarHead
        nextAction={() => setCurrentMonthDate(currentMonthDate.add(1, 'month'))}
        previousAction={() => setCurrentMonthDate(currentMonthDate.subtract(1, 'month'))}
        showPrev={
          allowPastDates || currentMonthDate.month() > dayjs().month() || currentMonthDate.year() > dayjs().year()
        }
      >
        <div className="font-semibold leading-regular text-sm">{currentMonthDate.format('MMM YYYY')}</div>
      </CalendarHead>

      <div className="border-y border-solid border-gray-ui-700 py-6 px-2">
        <CalendarWeekDayLabels className={dayClasses} />
        <CalendarDaysGrid
          calendarDate={dayjs(calendarDate)}
          setCurrentDate={date => setCurrentDate(date)}
          currentMonthDate={currentMonthDate}
          className={dayClasses}
          allowPastDates={allowPastDates}
        />
      </div>

      <CalendarFooter timezone={getUserTimezone()} locale={locale}>
        <TimeInput
          onChange={value => setCurrentTime(value.toString())}
          min={isToday ? currentDate.format('HH:mm') : ''}
          theme={'light'}
          error={false}
          className={classNames('h-9 min-w-[68px]')}
          value={currentTime}
        />
        <Button
          shape={'default'}
          color={'black'}
          size={'md'}
          onClick={apply}
          className="w-full"
          disabled={!getAssembledISOString()}
        >
          {locale === 'ru' ? 'Применить' : 'Apply'}
        </Button>
      </CalendarFooter>
    </div>
  );
}
