import { useMemo } from 'react';
import { useForm } from 'react-hook-form';

import { isBefore } from 'date-fns';

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

export type UseScheduleDrawerStateProps = {
  isReschedule?: boolean;
  initialValues?: {
    date: string;
    hours: number;
    minutes: number;
    sendPush?: boolean;
  };
  canSendPush?: boolean;
  isLoading?: boolean;
  onSchedulePost: (date: string, sendPush: boolean) => void;
  allowsOnlyChangingPush?: boolean;
};

export function useScheduleDrawerState(props: UseScheduleDrawerStateProps) {
  const {
    isReschedule = false,
    initialValues,
    canSendPush = false,
    isLoading = false,
    onSchedulePost,
    allowsOnlyChangingPush = false,
  } = props;

  const { t } = useTranslation(['post', 'group']);
  const form = useForm<{
    hours: string;
    minutes: string;
    date: Date | null;
    sendNotification: boolean;
  }>({
    defaultValues: {
      hours: initialValues?.hours?.toString() || '',
      minutes: initialValues?.minutes?.toString() || '',
      date: initialValues?.date ? new Date(initialValues.date) : null,
      sendNotification: !!initialValues?.sendPush,
    },
  });

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

  const dateError = useMemo(() => {
    if (!date || !hours || !minutes) {
      return false;
    }

    date.setHours(parseInt(hours, 10), Number(minutes));
    return isBefore(date, new Date());
  }, [date, hours, minutes]);

  const hasValidDateTime = () => {
    const hoursNum = parseInt(hours || '0', 10);
    const minutesNum = parseInt(minutes || '0', 10);
    return (
      date &&
      hours &&
      hoursNum >= 0 &&
      hoursNum <= 23 &&
      minutes &&
      minutesNum >= 0 &&
      minutesNum <= 59 &&
      !dateError
    );
  };

  const sendNotificationIsDirty = form.formState.dirtyFields.sendNotification;
  const dateIsDirty = form.formState.dirtyFields.date;
  const hoursIsDirty = form.formState.dirtyFields.hours;
  const minutesIsDirty = form.formState.dirtyFields.minutes;

  const dateOrTimeIsDirty = dateIsDirty || hoursIsDirty || minutesIsDirty;

  const handleSchedule = () => {
    const hoursNum = parseInt(hours || '0', 10);
    const minutesNum = parseInt(minutes || '0', 10);
    if (hasValidDateTime() && date) {
      date.setHours(hoursNum, minutesNum);
      onSchedulePost(date.toISOString(), sendNotification);
    }
  };

  const onlySendPush = allowsOnlyChangingPush && sendNotificationIsDirty;
  let title = '';
  if (onlySendPush && !dateOrTimeIsDirty) {
    title = t('group:send_post_notification');
  } else {
    title = isReschedule
      ? t('post:reschedule_post')
      : t('post:schedule_post_web');
  }

  const isDisabled = !(
    (hasValidDateTime() && dateOrTimeIsDirty) ||
    onlySendPush
  );

  return {
    form,
    canSendPush,
    dateError,
    isLoading,
    handleSchedule,
    title,
    isDisabled,
    isReschedule,
    initialValues,
    resetForm: () =>
      form.reset({
        hours: '',
        minutes: '',
        date: null,
        sendNotification: false,
      }),
  };
}
