import { FormikValues, useFormikContext } from 'formik';
import React, { useContext, useMemo } from 'react';
import { useHistory } from 'react-router-dom';
import { BulkEditContext } from '../../Explorer/BulkEdit/BulkEditContext';
import { QuickEditContext } from '../../Explorer/QuickEdit/QuickEditContext';
import { IconName } from '../../Icons';
import {
  PageHeader,
  PageHeaderActionItemProps,
  PageHeaderActionType,
  PageHeaderProps,
} from '../../PageHeader';
import { PageHeaderJsActionProps } from '../../PageHeader/PageHeaderAction';
import { useTitle } from '../helpers/useTitle';

/**
 * Handles showRefresh and cancel buttons based on form states
 */
export const FormStationHeader: React.FC<
  Omit<PageHeaderProps, 'title'> & {
    titleProperty?: string;
    defaultTitle?: string;
    cancelNavigationUrl?: string;
    setTabTitle?: boolean;
    showSaveHeaderAction?: boolean;
    saveHeaderActionConfig?: Pick<PageHeaderJsActionProps, 'label' | 'icon'>;
    setValidationError: () => void;
  }
> = ({
  titleProperty,
  defaultTitle,
  subtitle,
  cancelNavigationUrl,
  className,
  setTabTitle,
  showSaveHeaderAction,
  saveHeaderActionConfig = {
    label: 'Save',
    icon: IconName.Save,
  },
  setValidationError,
}) => {
  const { dirty, submitForm, resetForm, validateForm } =
    useFormikContext<FormikValues>();
  const quickEditContext = useContext(QuickEditContext);
  const bulkEditContext = useContext(BulkEditContext);

  const history = useHistory();

  const title = useTitle(titleProperty, defaultTitle);

  const actions: PageHeaderActionItemProps[] = useMemo(() => {
    const actionItems: PageHeaderActionItemProps[] = [];

    if (dirty) {
      actionItems.push({
        label: 'Undo Changes',
        icon: IconName.Undo,
        kind: 'action',
        actionType: PageHeaderActionType.Context,
        onClick: () => {
          resetForm();
        },
      });

      if (showSaveHeaderAction) {
        actionItems.push({
          label: saveHeaderActionConfig.label,
          icon: saveHeaderActionConfig.icon,
          confirmationMode: bulkEditContext ? 'Simple' : 'None',
          kind: 'action',
          actionType: PageHeaderActionType.Context,
          onClick: async () => {
            if (quickEditContext?.isQuickEditMode) {
              quickEditContext.refresh();
            } else if (bulkEditContext?.isBulkEditMode) {
              const errors = await validateForm();
              if (Object.keys(errors).length > 0) {
                setValidationError();
                return;
              }

              await submitForm();
              history.replace(history.location.pathname);
            } else {
              history.replace(history.location.pathname);
            }
          },
        });
      }
    }

    if (quickEditContext?.detailsLink !== undefined) {
      actionItems.push({
        label: 'Open',
        icon: IconName.ChevronRight,
        kind: 'action',
        path: quickEditContext.detailsLink,
      });
    }

    if (bulkEditContext?.isBulkEditMode) {
      actionItems.push({
        label: 'Cancel',
        icon: IconName.X,
        kind: 'action',
        onClick: () => {
          resetForm();
          bulkEditContext.cancel();
        },
      });
    }

    if (cancelNavigationUrl) {
      actionItems.push({
        label: 'Cancel',
        icon: IconName.X,
        kind: 'action',
        onClick: () => {
          resetForm();
          // If the form has errors, Navigation needs to be wrapped in a promise or timeout.
          Promise.resolve().then(() => history.push(cancelNavigationUrl));
        },
      });
    }

    return actionItems;
  }, [
    bulkEditContext,
    cancelNavigationUrl,
    dirty,
    history,
    quickEditContext,
    resetForm,
    saveHeaderActionConfig.icon,
    saveHeaderActionConfig.label,
    setValidationError,
    showSaveHeaderAction,
    submitForm,
    validateForm,
  ]);

  return (
    <PageHeader
      title={title}
      subtitle={subtitle}
      className={className}
      setTabTitle={setTabTitle}
      actions={actions}
    />
  );
};
