import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import "core-js/modules/es.regexp.exec.js";
import "core-js/modules/es.string.replace.js";
import "core-js/modules/es.array.iterator.js";
import "core-js/modules/web.dom-collections.iterator.js";
import Icon, { createFromIconfontCN } from '@ant-design/icons';
import { isImg, isUrl, useMountMergeState } from '../../../utils';
import Menu from '../../../menu';
import Skeleton from '../../../skeleton';
import classNames from 'classnames';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import defaultSettings from '../../defaultSettings';
import { getOpenKeysFromMenuData } from '../../utils/utils';
import MenuCounter from './Counter';
import { omit } from 'lodash';

// todo
import { jsx as _jsx } from "react/jsx-runtime";
import { createElement as _createElement } from "react";
let IconFont = createFromIconfontCN({
  scriptUrl: defaultSettings.iconfontUrl
});

// Allow menu.js config icon as string or ReactNode
//   icon: 'setting',
//   icon: 'icon-geren' #For Iconfont ,
//   icon: 'http://demo.com/icon.png',
//   icon: '/favicon.png',
//   icon: <Icon type="setting" />,
const getIcon = (icon, iconPrefixes = 'icon-') => {
  if (typeof icon === 'string' && icon !== '') {
    if (isUrl(icon) || isImg(icon)) {
      return /*#__PURE__*/_jsx(Icon, {
        component: () => /*#__PURE__*/_jsx("img", {
          src: icon,
          alt: "icon",
          className: "ant-pro-sider-menu-icon"
        })
      });
    }
    if (icon.startsWith(iconPrefixes)) {
      return /*#__PURE__*/_jsx(IconFont, {
        type: icon
      });
    }
  }
  return icon;
};
export class MenuUtil {
  constructor(props) {
    _defineProperty(this, "props", void 0);
    _defineProperty(this, "getNavMenuItems", (menusData = [], isChildren) => menusData.map(item => this.getSubMenuOrItem(item, isChildren)).filter(item => item));
    /** Get SubMenu or Item */
    _defineProperty(this, "getSubMenuOrItem", (item, isChildren) => {
      const children = item === null || item === void 0 ? void 0 : item.children;
      const {
        iconPrefixes
      } = this.props;
      if (Array.isArray(children) && children.length > 0) {
        const name = this.getIntlName(item);
        const {
          subMenuItemRender,
          prefixCls,
          menu
        } = this.props;
        //  get defaultTitle by menuItemRender
        const defaultTitle = /*#__PURE__*/_jsx("span", {
          className: `${prefixCls}-menu-item`,
          title: name,
          children: /*#__PURE__*/_jsx("span", {
            className: `${prefixCls}-menu-item-title`,
            children: name
          })
        });

        // subMenu only title render
        const title = subMenuItemRender ? subMenuItemRender({
          ...item,
          isUrl: false
        }, defaultTitle, this.props) : defaultTitle;
        return {
          type: (menu === null || menu === void 0 ? void 0 : menu.type) === 'group' ? 'group' : undefined,
          label: title,
          children: this.getNavMenuItems(children, true),
          onTitleClick: item.onTitleClick,
          key: item.key || item.path,
          icon: isChildren ? null : getIcon(item.icon, iconPrefixes)
        };
      }
      return {
        label: this.getMenuItemPath(item),
        title: this.getIntlName(item),
        key: item.key || item.path,
        disabled: item.disabled,
        icon: isChildren ? null : getIcon(item.icon, iconPrefixes),
        onClick: e => {
          var _item$onTitleClick;
          if (item !== null && item !== void 0 && item.path && isUrl(item === null || item === void 0 ? void 0 : item.path)) {
            window.open(item.path, '_blank');
          }
          (_item$onTitleClick = item.onTitleClick) === null || _item$onTitleClick === void 0 ? void 0 : _item$onTitleClick.call(item, e);
        }
      };
    });
    _defineProperty(this, "getIntlName", item => {
      const {
        name,
        locale
      } = item;
      const {
        menu,
        formatMessage
      } = this.props;
      if (locale && (menu === null || menu === void 0 ? void 0 : menu.locale) !== false) {
        return formatMessage === null || formatMessage === void 0 ? void 0 : formatMessage({
          id: locale,
          defaultMessage: name
        });
      }
      return name;
    });
    /**
     * 判断是否是http链接.返回 Link 或 a Judge whether it is http link.return a or Link
     *
     * @memberof SiderMenu
     */
    _defineProperty(this, "getMenuItemPath", item => {
      const itemPath = this.conversionPath(item.path || '/');
      const {
        location = {
          pathname: '/'
        },
        isMobile,
        onCollapse,
        menuItemRender
      } = this.props;
      // if local is true formatMessage all name。
      const name = this.getIntlName(item);
      const {
        prefixCls
      } = this.props;
      const isHttpUrl = isUrl(itemPath);
      const defaultItem = /*#__PURE__*/_jsx("span", {
        className: classNames(`${prefixCls}-menu-item`, {
          [`${prefixCls}-menu-item-link`]: isHttpUrl
        }),
        children: /*#__PURE__*/_jsx("span", {
          className: `${prefixCls}-menu-item-title`,
          children: name
        })
      });
      if (menuItemRender) {
        const renderItemProps = {
          ...item,
          isUrl: isHttpUrl,
          itemPath,
          isMobile,
          replace: itemPath === location.pathname,
          onClick: () => {
            if (isHttpUrl) window.open(itemPath, '_blank');
            if (onCollapse) onCollapse(true);
          },
          children: undefined
        };
        return menuItemRender(renderItemProps, defaultItem, this.props);
      }
      return defaultItem;
    });
    _defineProperty(this, "conversionPath", path => {
      if (path && path.indexOf('http') === 0) {
        return path;
      }
      return `/${path || ''}`.replace(/\/+/g, '/');
    });
    this.props = props;
  }
}

/**
 * 生成openKeys 的对象，因为设置了openKeys 就会变成受控，所以需要一个空对象
 *
 * @param BaseMenuProps
 */
const getOpenKeysProps = (openKeys, {
  layout,
  collapsed
}) => {
  let openKeysProps = {};
  if (openKeys && !collapsed && ['side', 'mix'].includes(layout || 'mix')) {
    openKeysProps = {
      openKeys
    };
  }
  return openKeysProps;
};
const BaseMenu = props => {
  const {
    theme,
    mode,
    className,
    handleOpenChange,
    style,
    menuData,
    menu,
    matchMenuKeys,
    iconfontUrl,
    collapsed,
    selectedKeys: propsSelectedKeys,
    onSelect,
    openKeys: propsOpenKeys
  } = props;

  // 用于减少 defaultOpenKeys 计算的组件
  const defaultOpenKeysRef = useRef([]);
  const {
    flatMenuKeys
  } = MenuCounter.useContainer();
  const [defaultOpenAll, setDefaultOpenAll] = useMountMergeState(menu === null || menu === void 0 ? void 0 : menu.defaultOpenAll);
  const [openKeys, setOpenKeys] = useMountMergeState(() => {
    if (menu !== null && menu !== void 0 && menu.defaultOpenAll) {
      return getOpenKeysFromMenuData(menuData) || [];
    }
    if (propsOpenKeys === false) {
      return false;
    }
    return [];
  }, {
    value: propsOpenKeys === false ? undefined : propsOpenKeys,
    onChange: handleOpenChange
  });
  const [selectedKeys, setSelectedKeys] = useMountMergeState([], {
    value: propsSelectedKeys,
    onChange: onSelect ? keys => {
      if (onSelect && keys) {
        onSelect(keys);
      }
    } : undefined
  });
  useEffect(() => {
    if (menu !== null && menu !== void 0 && menu.defaultOpenAll || propsOpenKeys === false || flatMenuKeys.length) {
      return;
    }
    if (matchMenuKeys) {
      setOpenKeys(matchMenuKeys);
      setSelectedKeys(matchMenuKeys);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [matchMenuKeys.join('-')]);
  useEffect(() => {
    // reset IconFont
    if (iconfontUrl) {
      IconFont = createFromIconfontCN({
        scriptUrl: iconfontUrl
      });
    }
  }, [iconfontUrl]);
  useEffect(() => {
    // if pathname can't match, use the nearest parent's key
    if (matchMenuKeys.join('-') !== (selectedKeys || []).join('-')) {
      setSelectedKeys(matchMenuKeys);
    }
    if (!defaultOpenAll && propsOpenKeys !== false && matchMenuKeys.join('-') !== (openKeys || []).join('-')) {
      let newKeys = matchMenuKeys;
      // 如果不自动关闭，我需要把 openKeys 放进去
      if ((menu === null || menu === void 0 ? void 0 : menu.autoClose) === false) {
        newKeys = Array.from(new Set([...matchMenuKeys, ...(openKeys || [])]));
      }
      setOpenKeys(newKeys);
    } else if (menu !== null && menu !== void 0 && menu.ignoreFlatMenu && defaultOpenAll) {
      // 忽略用户手动折叠过的菜单状态，折叠按钮切换之后也可实现默认展开所有菜单
      setOpenKeys(getOpenKeysFromMenuData(menuData));
    } else if (flatMenuKeys.length > 0) setDefaultOpenAll(false);

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [matchMenuKeys.join('-'), collapsed]);
  const openKeysProps = useMemo(() => getOpenKeysProps(openKeys, props),
  // eslint-disable-next-line react-hooks/exhaustive-deps
  [openKeys && openKeys.join(','), props.layout, props.collapsed]);
  const [menuUtils] = useState(() => new MenuUtil(props));
  if (menu !== null && menu !== void 0 && menu.loading) {
    return /*#__PURE__*/_jsx("div", {
      style: mode !== null && mode !== void 0 && mode.includes('inline') ? {
        padding: 24
      } : {
        marginTop: 16
      },
      children: /*#__PURE__*/_jsx(Skeleton, {
        active: true,
        title: false,
        paragraph: {
          rows: mode !== null && mode !== void 0 && mode.includes('inline') ? 6 : 1
        }
      })
    });
  }
  const cls = classNames(className, {
    'top-nav-menu': mode === 'horizontal'
  });

  // sync props
  menuUtils.props = props;

  // 这次 openKeys === false 的时候的情况，这种情况下帮用户选中一次
  // 第二此不会使用，所以用了 defaultOpenKeys
  // 这里返回 null，是为了让 defaultOpenKeys 生效
  if (props.openKeys === false && !props.handleOpenChange) {
    defaultOpenKeysRef.current = matchMenuKeys;
  }
  const finallyData = props.postMenuData ? props.postMenuData(menuData) : menuData;
  if (finallyData && (finallyData === null || finallyData === void 0 ? void 0 : finallyData.length) < 1) {
    return null;
  }
  return /*#__PURE__*/_createElement(Menu, {
    ...openKeysProps,
    key: "Menu",
    mode: mode,
    items: menuUtils.getNavMenuItems(finallyData, false),
    defaultOpenKeys: defaultOpenKeysRef.current,
    theme: theme,
    selectedKeys: selectedKeys,
    style: style,
    className: cls,
    onOpenChange: setOpenKeys,
    ...omit(props.menuProps || {}, 'children')
  });
};
BaseMenu.defaultProps = {
  postMenuData: data => data || []
};
export default BaseMenu;