import Menu from "ant-design-vue/es/menu";
import fastEqual from "fast-deep-equal";
import { Icon } from "@mega-design/ui-vue";

const { Item, SubMenu } = Menu;

export default {
  components: { Icon },
  inject: ["defaultLayout"],
  props: {
    options: {
      type: Array,
      required: true,
    },
    menuTheme: {
      type: String,
      required: false,
      default: "dark",
    },
    mode: {
      type: String,
      required: false,
      default: "inline",
    },
    collapsed: {
      type: Boolean,
      required: false,
      default: false,
    },
    defaultSelectedKeys: Array,
    i18n: Object,
    openKeys: Array,
  },
  data() {
    return {
      selectedKeys: [],
      sOpenKeys: [],
      cachedOpenKeys: [],
    };
  },
  created() {
    this.updateMenu();
  },
  watch: {
    collapsed(val) {
      if (val) {
        this.cachedOpenKeys = this.sOpenKeys;
        this.sOpenKeys = [];
      } else {
        this.sOpenKeys = this.cachedOpenKeys;
      }
    },
    $route() {
      this.updateMenu();
    },
    sOpenKeys(val) {
      this.$emit("openChange", val);
      this.$emit("update:openKeys", val);
    },
  },
  methods: {
    renderIcon(h, icon) {
      return icon === "none"
        ? null
        : h("Icon", {
            attrs: {
              type: icon,
              size: 18,
              style: "margin-right: 4px",
            },
          });
    },
    renderMenuItem(h, menu) {
      return h(
        Item,
        {
          key: menu.id,
          on: {
            click: () => this.defaultLayout.goRoute(menu),
          },
        },
        [
          h(
            "div",
            {
              attrs: {
                style: "overflow:hidden;white-space:normal;text-overflow:clip;",
              },
            },
            [this.renderIcon(h, menu.icon || "none"), this.$t(menu.menuName)]
          ),
        ]
      );
    },
    renderSubMenu(h, menu) {
      const subItem = [
        h(
          "span",
          {
            slot: "title",
            attrs: {
              style: "overflow:hidden;white-space:normal;text-overflow:clip;",
            },
          },
          [this.renderIcon(h, menu.icon || "none"), this.$t(menu.menuName)]
        ),
      ];
      const itemArr = [];
      menu.children.forEach((item) => {
        itemArr.push(this.renderItem(h, item));
      });
      return h(SubMenu, { key: menu.id }, subItem.concat(itemArr));
    },
    renderItem(h, menu) {
      const { meta } = menu;
      if (!meta || !meta.invisible) {
        let renderChildren = false;
        const { children } = menu;
        if (children !== undefined) {
          for (let i = 0; i < children.length; i += 1) {
            const childMeta = children[i].meta;
            if (!childMeta || !childMeta.invisible) {
              renderChildren = true;
              break;
            }
          }
        }
        return menu.children && renderChildren
          ? this.renderSubMenu(h, menu)
          : this.renderMenuItem(h, menu);
      }
      return undefined;
    },
    renderMenu(h, menuTree) {
      const menuArr = [];
      menuTree.forEach((menu, i) => {
        menuArr.push(this.renderItem(h, menu, "0", i));
      });
      return menuArr;
    },
    updateMenu() {
      const selectedKeys =
        this.$route?.meta?.keyPath || this.$route?.query?.keyPath || undefined;
      if (typeof selectedKeys === "string") {
        this.selectedKeys = [selectedKeys];
      } else if (selectedKeys instanceof Array) {
        this.selectedKeys = [...selectedKeys];
      }
      // 去掉根节点的 parentcode 标识
      const openKeys = this.selectedKeys.slice(0, this.selectedKeys.length - 1);
      if (!fastEqual(openKeys, this.sOpenKeys)) {
        this.collapsed || this.mode === "horizontal"
          ? (this.cachedOpenKeys = openKeys)
          : (this.sOpenKeys = openKeys);
      }
    },
  },
  render(h) {
    return h(
      Menu,
      {
        props: {
          theme: this.menuTheme,
          mode: this.$props.mode,
          selectedKeys: this.defaultSelectedKeys
            ? this.defaultSelectedKeys
            : this.selectedKeys,
          openKeys: this.openKeys ? this.openKeys : this.sOpenKeys,
        },
        on: {
          "update:openKeys": (val) => {
            this.sOpenKeys = val;
          },
          click: (_obj) => {
            const obj = _obj;
            const { key, item } = obj;
            obj.selectedKeys = [key];
            const { index } = item;
            if (this.options[index]?.isFrame === "N") {
              this.$emit("select", obj);
            }
          },
        },
      },
      this.renderMenu(h, this.options)
    );
  },
};
