import React, { FC, useEffect } from 'react';
import { Prompt, useHistory } from 'react-router';
import { Box, FlexProps, Flex } from '@chakra-ui/react';
import Modal from '../modal';
import Space from '../space';
import { ConfigContext } from '../config-provider';
import defaultLocale from '../locale/en_US';
import useContextualSaveBarState from './useContextualSaveBarState';
import Button, { ButtonProps } from '../button';

interface confirmModalType {
  /** 取消的二次确认标题 */
  title?: string;
  /** 取消的二次确认内容 */
  content?: string;
  /** 取消的二次确认的 ok 按钮文字 */
  okText?: string;
  /** 取消的二次确认的 cancel 按钮文字 */
  cancelText?: string;
  /** 取消的二次确认的 ok 按钮 props */
  okButtonProps?: ButtonProps;
  /** 取消的二次确认的 cancel 按钮 props */
  cancelButtonProps?: ButtonProps;
}

export interface ContextualSaveBarProps extends FlexProps {
  /** 左上角区域 */
  logo?: React.ReactNode;
  /** 保存条中间显示的文字 */
  title?: string;
  /** 保存按钮文字 */
  okText?: string;
  /** 保存按钮属性 */
  okButtonProps?: ButtonProps;
  /** 取消按钮属性 */
  cancelButtonProps?: ButtonProps;
  /** 取消按钮文字 */
  cancelText?: string;
  /** 取消保存的二次确认 Modal 的属性 */
  cancelConfirmModal?: confirmModalType;
  /** 离开页面的二次确认 Modal 的属性 */
  leaveConfirmModal?: confirmModalType;
  /** 保存回调 */
  onOK?: () => void;
  /** 取消回调 */
  onCancel?: () => void;
  /** 当 visible 为 true 时，离开页面的回调，参数 path 为要跳转的路由 */
  onLeave?: (path: string) => void;
}

const ContextualSaveBar: FC<ContextualSaveBarProps> = ({
  logo,
  title,
  okText,
  okButtonProps,
  cancelText,
  cancelButtonProps,
  cancelConfirmModal,
  leaveConfirmModal,
  onOK,
  onCancel,
  onLeave,
  ...rest
}) => {
  const {
    locale: { ContextualSaveBar: locale } = { ContextualSaveBar: defaultLocale.ContextualSaveBar },
    logo: globalLogo,
  } = React.useContext(ConfigContext);
  const history = useHistory();

  const [visible, setVisible] = useContextualSaveBarState();

  useEffect(() => {
    const listener = (e: BeforeUnloadEvent) => {
      e.preventDefault();
      e.returnValue = leaveConfirmModal?.content || locale?.leavePageMessage;
    };

    if (visible) {
      window.addEventListener('beforeunload', listener);
    }

    return () => {
      window.removeEventListener('beforeunload', listener);
    };
  }, [leaveConfirmModal?.content, locale?.leavePageMessage, visible]);

  const handleLeaveConfirm = (pathname: string) =>
    Modal.confirm({
      title: leaveConfirmModal?.title || locale?.title,
      content: leaveConfirmModal?.content || locale?.leavePageMessage,
      okText: leaveConfirmModal?.okText || locale?.leavePageText,
      okButtonProps: {
        danger: true,
        ...leaveConfirmModal?.okButtonProps,
      },
      cancelButtonProps: leaveConfirmModal?.cancelButtonProps,
      onOk: () => {
        setVisible(false);
        setTimeout(() => {
          if (onLeave) {
            onLeave(pathname);
          } else {
            history.push(pathname);
          }
        });
      },
    });

  const handleCancelConfirm = () =>
    Modal.confirm({
      title: cancelConfirmModal?.title || locale?.title,
      content: cancelConfirmModal?.content || locale?.message,
      okText: cancelConfirmModal?.okText || locale?.primaryAction,
      cancelText: cancelConfirmModal?.cancelText || locale?.secondaryAction,
      okButtonProps: {
        danger: true,
        ...cancelConfirmModal?.okButtonProps,
      },
      cancelButtonProps: cancelConfirmModal?.cancelButtonProps,
      onOk: () => {
        setVisible(false);
        if (onCancel) {
          setTimeout(onCancel);
        }
      },
    });

  return visible ? (
    <Flex
      pos="fixed"
      top={0}
      left={0}
      zIndex={99}
      align="center"
      justify="space-between"
      w="100%"
      h="56px"
      bg="rgb(32, 33, 35)"
      boxShadow="0 2px 4px rgba(0, 0, 0, 0.1)"
      {...rest}
    >
      <Box display={{ base: 'none', md: 'flex' }} p="0 16px" color="#fff" w={{ md: '240px' }}>
        {logo || globalLogo}
      </Box>
      <Flex
        flex="1 1 auto"
        align="center"
        justify="space-between"
        maxW="5xl"
        m="0 auto"
        px={{ base: 4, sm: 5, lg: 8 }}
      >
        <Box color="#fff" fontWeight={600} fontSize="16px">
          {title || locale?.unsavedChanges}
        </Box>
        <Space size={12}>
          <Button {...cancelButtonProps} onClick={() => handleCancelConfirm()}>
            {cancelText || locale?.discardText}
          </Button>
          <Button type="primary" {...okButtonProps} onClick={() => onOK?.()}>
            {okText || locale?.saveText}
          </Button>
        </Space>
      </Flex>
      <Prompt
        when={visible}
        message={({ pathname, query }: any) => {
          if (Object.keys(query).length > 0) {
            handleLeaveConfirm(`${pathname}?${new URLSearchParams(query).toString()}`);
          } else {
            handleLeaveConfirm(pathname);
          }
          return false;
        }}
      />
    </Flex>
  ) : null;
};

export default ContextualSaveBar;
