import { Form as FormikForm, Formik } from 'formik';
import React from 'react';
import NavigationPrompt from 'react-router-navigation-prompt';
import { Icon } from '../components/icon';
import { Confirm } from '../components/confirm';
import { SConfirmModalContent } from '../s-components/s-confirm-modal-content';
import { bem } from 'utils/bem';

interface Props<T> {
  initialValues: T;
  onSubmit(values: T): void;
  useNavigationPrompt?: boolean;
  enableReinitialize?: boolean;
  beforeDismiss?(value: T): void;
  children: React.ReactChildren | React.ReactChild;
}

const modalClasses = bem('confirm-modal-content');

export const Form = React.memo(
  <T,>({
    initialValues,
    onSubmit,
    useNavigationPrompt = false,
    beforeDismiss,
    children,
    enableReinitialize,
  }: Props<T>) => {
    return (
      <Formik initialValues={initialValues} onSubmit={onSubmit} enableReinitialize={enableReinitialize}>
        {({ dirty, isSubmitting, isValid, values }) => {
          const discardChangesHandler = onConfirm => {
            if (beforeDismiss) beforeDismiss(values);
            onConfirm();
          };

          const blockNavigation = ((dirty && !isSubmitting) || !isValid) && useNavigationPrompt;

          return (
            <>
              <FormikForm>{children}</FormikForm>
              {useNavigationPrompt && (
                <NavigationPrompt
                  // while "when" === true history navigation is locked
                  when={blockNavigation}
                  allowGoBack
                  disableNative
                >
                  {({ onConfirm, onCancel }) => (
                    <Confirm
                      visible
                      onOk={() => discardChangesHandler(onConfirm)}
                      okText="Discard"
                      cancelText="Cancel"
                      width="400px"
                      renderHeader={false}
                      onCancel={onCancel}
                    >
                      <SConfirmModalContent>
                        <div className={modalClasses('header-container')}>
                          <div className={modalClasses('title')}>
                            Are you sure you want to discard
                            <br />
                            changes and leave page?
                          </div>
                          <Icon onClick={onCancel} size="general" name="close" className={modalClasses('close-icon')} />
                        </div>
                        <div className={modalClasses('content-text')}>Unsaved changes will be lost.</div>
                      </SConfirmModalContent>
                    </Confirm>
                  )}
                </NavigationPrompt>
              )}
            </>
          );
        }}
      </Formik>
    );
  }
);
