import { IBizContext, Namespace } from '@ibiz-template/core';
import {
  AppMenuModel,
  AppMenuItemModel,
  IPSAppMenuItem,
} from '@ibiz-template/model';
import { useAppMenuController, useNamespace } from '@ibiz-template/vue-util';
import {
  defineComponent,
  getCurrentInstance,
  onMounted,
  Ref,
  ref,
  watch,
} from 'vue';
import { AppMenuController } from '@ibiz-template/controller';
import '@ibiz-template/theme/style/components/widgets/app-menu/app-menu.scss';
/**
 * 递归生成菜单数据，递给 antd 的 Menu 组件
 *
 * @author chitanda
 * @date 2022-07-25 10:07:28
 * @param {AppMenuItemModel[]} items
 * @return {*}  {any[]}
 */
function getMenus(items: AppMenuItemModel[]): IData[] {
  return items.map(item => {
    const data: IData = {
      key: item.source.id,
      label: item.label,
      image: item.image,
    };
    if (item.children) {
      data.children = getMenus(item.children);
    }
    return data;
  });
}

/**
 * 绘制菜单项
 * @author lxm
 * @date 2022-08-16 14:08:20
 * @param {IData} menu
 * @returns {*}
 */
function renderMenuItem(
  menu: IData,
  collapseChange: boolean,
  ns: Namespace,
  c: AppMenuController,
) {
  if (!c.menuItemsState[menu.key].visible) {
    return;
  }
  return !collapseChange ? (
    <i-menu-item class={ns.e('item')} name={menu.key}>
      <app-icon class={ns.e('icon')} icon={menu.image}></app-icon>
      {menu.label}
    </i-menu-item>
  ) : (
    <i-tooltip
      class={ns.b('tooltip')}
      content={menu.label}
      placement={'left'}
      theme='light'
    >
      <i-menu-item class={ns.e('item')} name={menu.key}>
        <app-icon class={ns.e('icon')} icon={menu.image}></app-icon>
        {!menu.image ? menu.label.slice(0, 1) : null}
      </i-menu-item>
    </i-tooltip>
  );
}

/**
 * 绘制收缩分组菜单项
 * @param {IData} menu
 * @return {*}
 * @author: zhujiamin
 * @Date: 2022-09-08 16:39:15
 */
function renderDropDownMenuItem(
  menu: IData,
  collapseChange: boolean,
  ns: Namespace,
  c: AppMenuController,
) {
  if (!c.menuItemsState[menu.key].visible) {
    return;
  }
  return (
    <i-dropdown-item class={ns.be('submenu', 'item')} name={menu.key}>
      <i-menu-item name={menu.key}>{menu.label}</i-menu-item>
    </i-dropdown-item>
  );
}

/**
 * 绘制子菜单
 * @author lxm
 * @date 2022-08-16 14:08:29
 * @param {IData} subMenu
 * @returns {*}
 */
function renderSubmenu(
  isFirst: boolean,
  subMenu: IData,
  collapseChange: boolean,
  ns: Namespace,
  c: AppMenuController,
) {
  if (!c.menuItemsState[subMenu.key].visible) {
    return;
  }
  return !collapseChange ? (
    <i-submenu name={subMenu.key}>
      <template slot='title'>
        <app-icon class={ns.e('icon')} icon={subMenu.image}></app-icon>
        {subMenu.label}
      </template>
      {subMenu.children.map((item: IData) => {
        if (item.children) {
          return renderSubmenu(false, item, collapseChange, ns, c);
        }
        return renderMenuItem(item, collapseChange, ns, c);
      })}
    </i-submenu>
  ) : (
    <i-dropdown placement='left' class={ns.b('submenu')}>
      <div class={ns.be('submenu', 'title')}>
        {isFirst
          ? [
              <app-icon class={ns.e('icon')} icon={subMenu.image}></app-icon>,
              !subMenu.image ? subMenu.label.slice(0, 1) : null,
            ]
          : [
              <app-icon class={ns.e('icon')} icon={subMenu.image}></app-icon>,
              subMenu.label,
            ]}
        {isFirst ? null : <i-icon type='ios-arrow-forward' />}
      </div>
      <i-dropdown-menu class={ns.be('submenu', 'list')} slot='list'>
        {subMenu.children.map((item: IData) => {
          if (item.children) {
            return renderSubmenu(false, item, collapseChange, ns, c);
          }
          return renderDropDownMenuItem(item, collapseChange, ns, c);
        })}
      </i-dropdown-menu>
    </i-dropdown>
  );
}

export const AppMenu = defineComponent({
  name: 'AppMenu',
  props: {
    modelData: AppMenuModel,
    context: IBizContext,
    collapseChange: Boolean,
    currentPath: String,
  },
  setup(props, { emit }) {
    const { proxy } = getCurrentInstance()!;
    const c = useAppMenuController(proxy, props.modelData!, props.context!, {});
    const menus = ref<IData[]>([]);
    // 默认激活菜单项
    const defaultActive = ref('');
    // 默认展开菜单项数组
    const defaultOpens: Ref<string[]> = ref([]);
    // 路由对象
    const route = proxy.$route;

    c.nerve.self.evt.on('created', () => {
      menus.value = getMenus(c.model.items);
    });

    let menuClickDoing = false;

    const onClick = async (key: string) => {
      menuClickDoing = true;
      await c.onClickMenuItem(key);
      menuClickDoing = false;
    };

    const ns = useNamespace('app-menu');

    // 手动更新iView菜单
    const updateMenu = () => {
      setTimeout(() => {
        if (proxy.$refs.menu) {
          const menu: IData = proxy.$refs.menu;
          menu.updateActiveName();
          menu.updateOpened();
        }
      }, 500);
    };

    // 菜单选中回显，监听视图传进来的currentPath
    watch(
      () => props.currentPath,
      (newVal, oldVal) => {
        // 新旧值不一样，且新值不为空时变更
        if (newVal !== oldVal && newVal) {
          if (menuClickDoing === true) {
            emit('menuRouteChange');
          }
          const findItem = c.model.allItems.find(item => {
            return item.viewModelPath === newVal;
          });
          if (findItem) {
            defaultActive.value = findItem.source.id;
            updateMenu();
          }
        }
      },
      { deep: true, immediate: true },
    );

    // 处理默认展开父菜单
    const handleDefaultOpen = (parent: IPSAppMenuItem) => {
      if (parent && parent.itemType === 'MENUITEM') {
        const findIndex = defaultOpens.value.findIndex(open => {
          return open === parent.id;
        });
        if (findIndex === -1) {
          defaultOpens.value.push(parent.id);
        }
        const gParent = parent.getParentPSModelObject() as IPSAppMenuItem;
        if (gParent) {
          handleDefaultOpen(gParent);
        }
      }
    };

    // 回显完成后，遍历展开父菜单
    watch(
      () => defaultActive.value,
      newVal => {
        const findItem = c.model.allItems.find(item => {
          return newVal === item.id;
        });
        if (findItem) {
          const parent =
            findItem.source.getParentPSModelObject() as IPSAppMenuItem;
          // 遍历取父菜单项
          handleDefaultOpen(parent);
          updateMenu();
        }
      },
    );

    onMounted(() => {
      // 默认激活的菜单项
      const defaultActiveMenuItem = c.model.allItems.find(item => {
        return item.source.openDefault && !item.source.hidden;
      });
      if (defaultActiveMenuItem && !route.params.view2) {
        defaultActive.value = defaultActiveMenuItem.id;
        onClick(defaultActive.value);
      }
      // 默认展开的菜单项数组
      const defaultOpensArr = c.model.allItems.filter(item => {
        return item.source.expanded && !item.source.hidden;
      });
      if (defaultOpensArr.length > 0) {
        defaultOpensArr.forEach(item => {
          defaultOpens.value.push(item.id);
        });
      }
      updateMenu();
    });

    return { menus, c, onClick, ns, defaultActive, defaultOpens };
  },
  render() {
    return (
      <i-menu
        ref={'menu'}
        active-name={this.defaultActive}
        open-names={this.defaultOpens}
        on-on-select={this.onClick}
        theme='light'
        width='auto'
        class={[this.ns.b(), this.ns.is('collapse', this.collapseChange)]}
      >
        {this.menus.map(item => {
          if (item.children?.length > 0) {
            return renderSubmenu(
              true,
              item,
              this.collapseChange,
              this.ns,
              this.c,
            );
          }
          return renderMenuItem(item, this.collapseChange, this.ns, this.c);
        })}
      </i-menu>
    );
  },
});
