import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';

import { startOfDay } from 'date-fns';
import Stack from '@material-hu/mui/Stack';

import Button from '@material-hu/components/design-system/Buttons/Button';
import HuCircularProgress from '@material-hu/components/design-system/ProgressIndicators/Spinner';

import { useGetRequestToCalendar } from 'src/hooks/queryHooks/vacations';
import useLogEventInViewVisited from 'src/hooks/useLogEventInViewVisited';
import MonthInput from 'src/pages/dashboard/timeOff/components/calendar/inputs/MonthInput';
import RequestCalendarTable from 'src/pages/dashboard/timeOff/components/calendar/RequestCalendarTable';
import RequestStateLegend from 'src/pages/dashboard/timeOff/components/calendar/RequestStateLegend';
import { restoreMonthWithFirstPage } from 'src/pages/dashboard/timeOff/queries';
import { EventName } from 'src/types/amplitude';
import { useLokaliseTranslation } from 'src/utils/i18n';

import ManagerViewHeader from './shared/ManagerViewHeader';
import { type VacationsFilterReturn } from './shared/useVacationsFilter';

const DEFAULT_MONTH = new Date(startOfDay(new Date()));

export type CalendarViewProps = {
  filters: VacationsFilterReturn;
  isManagerView?: boolean;
};

export const CalendarView = (props: CalendarViewProps) => {
  const { filters, isManagerView = true } = props;

  const { t } = useLokaliseTranslation('time_off');
  const form = useForm({
    defaultValues: {
      month: DEFAULT_MONTH,
    },
  });

  const { watch, setValue } = form;
  const month = watch('month');

  const {
    data,
    count,
    isLoading,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useGetRequestToCalendar(month, filters.values, isManagerView);

  useEffect(() => {
    return () => {
      if (data?.length) {
        restoreMonthWithFirstPage(watch('month'), filters.values);
      }
    };
  }, []);

  useLogEventInViewVisited({
    properties: isManagerView ? { usersCount: count! } : undefined,
    amplitudeEvent: isManagerView
      ? EventName.TIME_OFF_MANAGE_CALENDAR_TAB_VISITED
      : EventName.TIME_OFF_PERSONAL_SPACE_CALENDAR_TAB_VISITED,
  });

  const handleOnClick = () => {
    restoreMonthWithFirstPage(month, filters.values);
    setValue('month', DEFAULT_MONTH);
  };

  return (
    <Stack
      sx={{
        p: 1,
        width: '100%',
        maxHeight: 'calc(100vh - 200px)',
        overflow: 'hidden',
      }}
    >
      <ManagerViewHeader
        title={t('calendar')}
        filters={filters}
        isManagerView={isManagerView}
      />
      <Stack
        sx={{
          flex: '0 1 auto',
          maxHeight: 'calc(100vh - 200px)',
          minHeight: 0,
          overflow: 'hidden',
          borderRadius: 2,
          border: theme =>
            `1px solid ${theme.palette.new.border.neutral.default}`,
        }}
      >
        <Stack
          sx={{
            flexDirection: 'row',
            alignItems: 'center',
            justifyContent: 'space-between',
            backgroundColor: theme =>
              theme.palette?.new.background.elements.default,
            width: '100%',
            borderRadius: 2,
            borderEndEndRadius: 0,
            borderEndStartRadius: 0,
          }}
        >
          <FormProvider {...form}>
            <Stack sx={{ flexDirection: 'row', alignItems: 'center' }}>
              <MonthInput
                filters={filters.values}
                name="month"
              />
              {(isLoading || isFetchingNextPage) && (
                <HuCircularProgress centered />
              )}
            </Stack>
            <Button
              variant="secondary"
              onClick={handleOnClick}
              sx={{ mr: 2 }}
            >
              {t('today')}
            </Button>
          </FormProvider>
        </Stack>
        {!isLoading && (
          <RequestCalendarTable
            fetchNextPage={fetchNextPage}
            hasNextPage={hasNextPage}
            isFetchingNextPage={isFetchingNextPage}
            isLoading={isLoading}
            requestsCalendar={data || []}
            month={month}
            count={count || 0}
          />
        )}
      </Stack>
      {!isLoading && isManagerView && (
        <Stack sx={{ flexShrink: 0, mt: 1 }}>
          <RequestStateLegend />
        </Stack>
      )}
    </Stack>
  );
};

export default CalendarView;
