import { useEffect, useState, useRef, FC } from 'react';
import { useBlocker } from 'react-router';

import { useModal } from '@material-hu/hooks/useModal';

import NewModal from '@material-hu/components/deprecated/NewModal';
import { useLokaliseTranslation } from 'src/utils/i18n';

const beforeUnloadHandler = (event: BeforeUnloadEvent) => {
  event.preventDefault();
  event.returnValue = true;
};

export type WarningModalProps = {
  onClose: () => void;
  onConfirm: () => void;
};

export type WarningModalType = FC<WarningModalProps>;

export const useUnsavedWarning = (
  WarningModal?: WarningModalType,
  disabledProp = false,
) => {
  const [disabled, setDisabled] = useState(disabledProp);
  const { t } = useLokaliseTranslation('general');

  useEffect(() => {
    setDisabled(disabledProp);
  }, [disabledProp]);

  let blocker = useBlocker(
    ({ currentLocation, nextLocation }) =>
      !disabled && currentLocation.pathname !== nextLocation.pathname,
  );

  const blockerRef = useRef(blocker);
  blockerRef.current = blocker;

  useEffect(() => {
    if (!disabled) {
      window.addEventListener('beforeunload', beforeUnloadHandler);
    }

    return () => {
      window.removeEventListener('beforeunload', beforeUnloadHandler);
    };
  }, [disabled]);

  const disableUnsavedWarning = () => setDisabled(true);
  const resetUnsavedWarning = () => setDisabled(disabledProp);

  const DefaultModal = ({ onClose, onConfirm }: WarningModalProps) => (
    <NewModal
      onClose={onClose}
      title={t('unsaved_changes.title')}
      textBody={t('unsaved_changes.description')}
      primaryButtonProps={{
        id: 'cancel-unsaved-warning-button',
        children: t('general:cancel'),
        variant: 'contained',
        color: 'primary',
        onClick: onClose,
      }}
      secondaryButtonProps={{
        id: 'confirm-unsaved-warning-button',
        children: t('unsaved_changes.confirm'),
        color: 'primary',
        variant: 'text',
        onClick: onConfirm,
      }}
    />
  );

  const { modal, showModal, closeModal } = useModal(
    WarningModal || DefaultModal,
    {
      fullWidth: true,
      maxWidth: 'sm',
    },
    {
      onClose: () => {
        closeModal();
        blocker.reset?.();
      },
      onConfirm: () => {
        blocker.proceed?.();
      },
    },
  );

  useEffect(() => {
    blocker.state === 'blocked' && showModal();
  }, [blocker.state]);

  useEffect(() => {
    return () => {
      if (blockerRef.current.state === 'blocked') {
        blockerRef.current.reset();
      }
    };
  }, []);

  return {
    modal,
    blocker,
    disableUnsavedWarning,
    resetUnsavedWarning,
  };
};

export default useUnsavedWarning;
