import {
  ConfigProviderContext,
  ConfigProviderProps,
  def,
} from "@/utils/configProvider";
import { ModalProps } from "./interface";
import {
  applyBoxStyle,
  applyModal,
  applyModalContainer,
  applyModalContent,
  applyModalFooter,
  applyModalHeader,
  applyModalMask,
  applyModalTitle,
  maskAnimation,
  modalAnimation,
  modalCloseIconStyle,
  deleteCssProps,
} from "./style";
import CloseIcon from "@mui/icons-material/Close";
import ErrorCircleIcon from "@mui/icons-material/ErrorOutlineRounded";
import InfoCircleIcon from "@mui/icons-material/InfoOutlined";
import SuccessCircleIcon from "@mui/icons-material/DoneAllOutlined";
import WarningCircleIcon from "@mui/icons-material/WarningOutlined";
import { AnimatePresence, motion } from "framer-motion";
import { forwardRef, ReactNode, useContext, useMemo } from "react";
import FocusLock from "react-focus-lock";
import { useHotkeys } from "react-hotkeys-hook";
import { Button, useTheme } from "@mui/material";
import { TriggerProvider } from "@/utils/trigger";
import { globalColor } from "@/utils/colorBuilder";

export const Modal = forwardRef<HTMLDivElement, ModalProps>((props, ref) => {
  const {
    withoutPadding,
    children,
    visible,
    type,
    mask = false,
    title,
    withoutLine = true,
    okLoading,
    maskClosable = true,
    hideCancel,
    closable,
    closeElement,
    okText,
    cancelText,
    okButtonProps,
    cancelButtonProps,
    footer = true,
    // footerAlign = "",
    focusLock = true,
    autoFocus = true,
    maskStyle,
    modalContentStyle,
    enableOnFormTags,
    onCancel,
    onOk,
    afterClose,
    afterOpen,
    z,
    ...otherProps
  } = props;

  const configProviderProps = useContext<ConfigProviderProps>(
    ConfigProviderContext
  );
  const locale = configProviderProps?.locale?.modal ?? def.modal;
  const theme = useTheme();
  // hot key
  useHotkeys(
    "Enter,Escape",
    (event) => {
      switch (event.key) {
        case "Enter":
          if (visible) {
            onOk?.();
          }
          break;
        case "Escape":
          if (visible) {
            onCancel?.();
          }
          break;
      }
    },
    {
      enableOnFormTags: enableOnFormTags ?? ["INPUT"],
    },
    [visible]
  );

  const normalIcon: ReactNode = useMemo(() => {
    if (type && title) {
      switch (type) {
        case "info":
          return (
            <InfoCircleIcon sx={{ color: globalColor("blue-03"), mr: "8px" }} />
          );
        case "error":
          return (
            <ErrorCircleIcon sx={{ color: globalColor("red-03"), mr: "8px" }} />
          );
        case "success":
          return (
            <SuccessCircleIcon
              sx={{ color: globalColor("green-03"), mr: "8px" }}
            />
          );
        case "warning":
          return (
            <WarningCircleIcon
              sx={{ color: globalColor("red-03"), mr: "8px" }}
            />
          );
        default:
          return <></>;
      }
    } else {
      return <></>;
    }
  }, [title, type]);

  return (
    <TriggerProvider renderInBody={false} zIndex={257}>
      <AnimatePresence>
        {visible && (
          <>
            {mask ? (
              <motion.div
                css={[applyModalMask(z), maskStyle]}
                variants={maskAnimation}
                animate="animate"
                exit="exit"
                initial="initial"
                transition={{ duration: 0.2 }}
              />
            ) : null}
            <div
              css={[applyModalContainer(z), modalContentStyle]}
              onClick={() => {
                if (maskClosable) {
                  onCancel?.();
                }
              }}
            >
              <motion.div
                onClick={(e) => {
                  e.stopPropagation();
                }}
                ref={ref}
                role="dialog"
                variants={modalAnimation}
                animate="animate"
                transition={{ duration: 0.2 }}
                exit="exit"
                initial="initial"
                css={[applyModal(), applyBoxStyle(props, theme)]}
                onAnimationComplete={(definition) => {
                  if (definition === "animate") {
                    afterOpen?.();
                  }
                  if (definition === "exit") {
                    afterClose?.();
                  }
                }}
                {...deleteCssProps(otherProps)}
              >
                {title && (
                  <div css={applyModalHeader(closable, withoutLine)}>
                    {normalIcon}
                    <div css={applyModalTitle(theme)}>{title}</div>
                    {closable && (
                      <>
                        {closeElement ? (
                          closeElement
                        ) : (
                          <div css={modalCloseIconStyle} onClick={onCancel}>
                            <CloseIcon
                              sx={{
                                fontSize: "14px",
                                color: globalColor("grayBlue-02"),
                              }}
                            />
                          </div>
                        )}
                      </>
                    )}
                  </div>
                )}
                {focusLock ? (
                  <FocusLock disabled={!visible} autoFocus={autoFocus}>
                    {children && (
                      <div css={applyModalContent(withoutPadding, theme)}>
                        {children}
                      </div>
                    )}
                  </FocusLock>
                ) : (
                  children && (
                    <div css={applyModalContent(withoutPadding, theme)}>
                      {children}
                    </div>
                  )
                )}
                {footer && (
                  <div css={applyModalFooter(withoutLine)}>
                    {!hideCancel && (
                      <Button
                        type="button"
                        onClick={onCancel}
                        size="medium"
                        sx={{ color: theme.palette.text.secondary,flex: 1 }}
                      >
                        {cancelText || locale.cancelText}
                      </Button>
                    )}
                    {
                      <Button
                        type="button"
                        loading={okLoading}
                        size="medium"
                        color="error"
                        variant="contained"
                        onClick={onOk}
                        flex="1"
                        {...okButtonProps}
                      >
                        {okText || locale.okText}
                      </Button>
                    }
                  </div>
                )}
              </motion.div>
            </div>
          </>
        )}
      </AnimatePresence>
    </TriggerProvider>
  );
});

Modal.displayName = "Modal";
