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

import { isBefore } from 'date-fns';
import { times } from 'lodash-es';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import { type DrawerProps as HuDrawerProps } from '@material-hu/components/design-system/Drawer/types';
import HuFormDatePicker from '@material-hu/components/design-system/Inputs/DatePicker/form';
import HuFormInputSelect from '@material-hu/components/design-system/Inputs/Select/form';
import HuFormSwitcher from '@material-hu/components/design-system/Switcher/form';
import HuTitle from '@material-hu/components/design-system/Title';

import useHuGoTheme from 'src/hooks/useHuGoTheme';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';

import { type useScheduleDrawerState } from './useScheduleDrawerState';

const minutesOptions = times(6, i => ({
  value: (i * 10).toString(),
  label: (i * 10).toString().padStart(2, '0'),
}));

const hoursOptions = times(24, i => ({
  value: i.toString(),
  label: i.toString().padStart(2, '0'),
}));

type ScheduleDrawerContentProps = {
  canSendPush?: boolean;
  dateError?: boolean;
  isReschedule?: boolean;
  hasInitialValues?: boolean;
  onResetForm?: () => void;
};
const ScheduleDrawerContent = (props: ScheduleDrawerContentProps) => {
  const {
    canSendPush = false,
    isReschedule = false,
    hasInitialValues = false,
    onResetForm,
  } = props;

  const { t } = useTranslation();
  const HugoThemeProvider = useHuGoTheme();
  const minutesLabel = t('group:groups_minutes');
  const hoursLabel = t('group:hours');

  const form = useFormContext();
  const { date, hours, minutes } = form.watch();

  // Reset form when drawer opens for a new schedule (not reschedule and no initial values)
  useEffect(() => {
    if (!isReschedule && !hasInitialValues && onResetForm) {
      onResetForm();
    }
    // Adding dependencies would cause an infinite loop when the
    //  form is reset, as it causes the component to remount.
  }, []);

  // Handle custom validation when dependent fields change
  useEffect(() => {
    // Clear all custom errors first
    if (form.formState.errors.hours?.type === 'pastTime') {
      form.clearErrors('hours');
    }
    if (form.formState.errors.minutes?.type === 'pastTime') {
      form.clearErrors('minutes');
    }

    if (date && hours && minutes) {
      const selectedDate = new Date(date);
      const hoursNum = parseInt(hours, 10);
      const minutesNum = parseInt(minutes, 10);

      // First check if date+hour is already in the past (using 59 minutes to give benefit of doubt)
      // Should never happen since date picker is disabled for past dates
      const dateWithHourOnly = new Date(date);
      dateWithHourOnly.setHours(hoursNum, 59, 59, 999);

      if (isBefore(dateWithHourOnly, new Date())) {
        // Show error only on hour field
        form.setError('hours', {
          type: 'pastTime',
          message: t('post:hour_error_past_time'),
        });
      } else {
        // Hour is valid, now check full date+hour+minute
        selectedDate.setHours(hoursNum, minutesNum);

        if (isBefore(selectedDate, new Date())) {
          // Show error only on minute field
          form.setError('minutes', {
            type: 'pastTime',
            message: t('post:minute_error_past_time'),
          });
        }
      }
    }
  }, [date, hours, minutes, form]);

  return (
    <HugoThemeProvider>
      <Stack sx={{ gap: 3 }}>
        <Typography variant="body1">{t('group:schedule_post_info')}</Typography>
        <HuFormDatePicker
          name="date"
          inputProps={{
            label: t('group:date'),
            minDate: new Date(),
          }}
        />
        <Stack sx={{ gap: 0.5 }}>
          <HuTitle
            variant="S"
            title={t('group:time')}
          />
          <Stack
            sx={{
              flexDirection: 'row',
              alignItems: 'flex-start',
              gap: 2,
              minHeight: '105px',
            }}
          >
            <HuFormInputSelect
              name="hours"
              inputProps={{
                options: hoursOptions,
                placeholder: hoursLabel,
              }}
            />
            <HuFormInputSelect
              name="minutes"
              inputProps={{
                options: minutesOptions,
                placeholder: minutesLabel,
              }}
            />
          </Stack>
        </Stack>
        {canSendPush && (
          <HuFormSwitcher
            name="sendNotification"
            switcherProps={{
              sx: { width: '100%' },
              title: t('group:send_with_push'),
              description: t('group:send_push_info'),
            }}
          />
        )}
      </Stack>
    </HugoThemeProvider>
  );
};

function getScheduleDrawerConfig(
  scheduleDrawerState: ReturnType<typeof useScheduleDrawerState>,
  closeDrawer: () => void,
): Partial<HuDrawerProps> {
  const onSchedulePost = () => {
    scheduleDrawerState.handleSchedule();
    closeDrawer();
  };

  return {
    title: scheduleDrawerState.title,
    hasBackButton: true,
    children: (
      <FormProvider {...scheduleDrawerState.form}>
        <ScheduleDrawerContent
          canSendPush={scheduleDrawerState.canSendPush}
          isReschedule={scheduleDrawerState.isReschedule}
          hasInitialValues={!!scheduleDrawerState.initialValues}
          onResetForm={scheduleDrawerState.resetForm}
        />
      </FormProvider>
    ),
    primaryButtonProps: {
      children: scheduleDrawerState.title,
      variant: 'contained',
      loading: scheduleDrawerState.isLoading,
      onClick: onSchedulePost,
      disabled: scheduleDrawerState.isDisabled,
      fullWidth: true,
    },
  };
}

export default getScheduleDrawerConfig;
