<script lang="tsx">
import type { CSSProperties } from 'vue'

import { computed, defineComponent, toRef, unref } from 'vue'
import { useSplitMenu } from '@/layouts/default/menu/useLayoutMenu'
import { KingdeeBaseMenu } from '@/components/Menu'
import { SimpleMenu } from '@/components/SimpleMenu'
import { AppLogo } from '@/components/Application'

import { MenuModeEnum, MenuSplitTyeEnum } from '@/enums/menuEnum'

import { useMenuSetting } from '@/hooks/setting/useMenuSetting'
import { ScrollContainer } from '@/components/Container'

import { useGo } from '@/hooks/web/usePage'
import { openWindow } from '@/utils'
import { propTypes } from '@/utils/propTypes'
import { isHttpUrl } from '@/utils/is'
import { useRootSetting } from '@/hooks/setting/useRootSetting'
import { useAppInject } from '@/hooks/web/useAppInject'
import { useDesign } from '@/hooks/web/useDesign'
import type { Menu } from '@/router/types'
import { useMultipleTabStore } from '@/store/modules/multipleTab'

export default defineComponent({
  name: 'KingdeeTopMenu',
  props: {
    theme: propTypes.oneOf(['light', 'dark']),

    splitType: {
      type: Number as PropType<MenuSplitTyeEnum>,
      default: MenuSplitTyeEnum.NONE,
    },

    isHorizontal: propTypes.bool,
    // menu Mode
    menuMode: {
      type: [String] as PropType<Nullable<MenuModeEnum>>,
      default: '',
    },
    isScoped: {
      type: Boolean,
      default: false,
    },
  },
  setup(props) {
    const go = useGo()

    const {
      getMenuMode,
      getMenuType,
      getMenuTheme,
      getCollapsed,
      getCollapsedShowTitle,
      getAccordion,
      getIsHorizontal,
      getIsSidebarType,
      getSplit,
    } = useMenuSetting()
    const { getShowLogo } = useRootSetting()

    const { prefixCls } = useDesign('layout-menu')

    const { menusRef } = useSplitMenu(toRef(props, 'splitType'))

    const { getIsMobile } = useAppInject()

    const getComputedMenuMode = computed(() => (unref(getIsMobile) ? MenuModeEnum.INLINE : props.menuMode || unref(getMenuMode)))

    const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme))

    const getIsShowLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType))

    const getUseScroll = computed(() => {
      return (
        !unref(getIsHorizontal)
        && (unref(getIsSidebarType) || props.splitType === MenuSplitTyeEnum.LEFT || props.splitType === MenuSplitTyeEnum.NONE)
      )
    })

    const getWrapperStyle = computed((): CSSProperties => {
      return {
        height: `calc(100% - ${unref(getIsShowLogo) ? '48px' : '0px'})`,
      }
    })

    const getLogoClass = computed(() => {
      return [
        `${prefixCls}-logo`,
        unref(getComputedMenuTheme),
        {
          [`${prefixCls}--mobile`]: unref(getIsMobile),
        },
      ]
    })

    const tabStore = useMultipleTabStore()
    const getTabsState = computed(() => {
      return tabStore.getTabList.filter(item => !item.meta?.hideTab)
    })

    /**
     * 只显示已经打开的一级菜单
     * @param menus
     * @param openedFullPath
     */
    function filterMenus(menus: Menu[], openedFullPath: string[]): Menu[] {
      return menus
        .map((menu) => {
          // 如果当前菜单的路径在 openedFullPath 中，直接保留
          if (openedFullPath.includes(menu.path))
            return menu

          // 如果当前菜单有子菜单，递归过滤子菜单
          if (menu.children && menu.children.length > 0) {
            const filteredChildren = filterMenus(menu.children, openedFullPath)

            // 如果过滤后的子菜单不为空，保留当前菜单并更新子菜单
            if (filteredChildren.length > 0) {
              return {
                ...menu,
                children: filteredChildren,
              }
            }
          }

          // 如果当前菜单的路径不在 openedFullPath 中，且没有子菜单，则过滤掉
          return null
        })
        .filter(menu => menu !== null) as Menu[]
    }

    function getFirstPathSegment(path: string): string {
      const trimmedPath = path.replace(/^\/+/, '/')

      const segments = trimmedPath.split('/')

      const firstSegment = segments.find(segment => segment !== '')

      return firstSegment ? `/${firstSegment}` : '/'
    }

    const getCommonProps = computed(() => {
      const openedPath: string[] = []
      const openedFullPath: string[] = []
      const tabs = unref(getTabsState)
      for (let i = 0; i < tabs.length; i++) {
        openedPath.push(getFirstPathSegment(tabs[i].path))
        openedFullPath.push(tabs[i].path)
      }

      const filterMenu = filterMenus(unref(menusRef), openedFullPath)
      const menus = unref(menusRef)
      return {
        menus: filterMenu,
        beforeClickFn: beforeMenuClickFn,
        items: menus,
        theme: unref(getComputedMenuTheme),
        accordion: unref(getAccordion),
        collapse: unref(getCollapsed),
        collapsedShowTitle: unref(getCollapsedShowTitle),
        onMenuClick: handleMenuClick,
      }
    })
    /**
     * click menu
     * @param path
     */

    function handleMenuClick(path: string) {
      go(path)
    }

    /**
     * before click menu
     * @param path
     */
    async function beforeMenuClickFn(path: string) {
      if (!isHttpUrl(path))
        return true

      openWindow(path)
      return false
    }

    function renderHeader() {
      if (!unref(getIsShowLogo) && !unref(getIsMobile))
        return null

      return <AppLogo showTitle={!unref(getCollapsed)} class={unref(getLogoClass)} theme={unref(getComputedMenuTheme)} />
    }

    function renderMenu() {
      const { menus, ...menuProps } = unref(getCommonProps)
      if (!menus || !menus.length)
        return null
      return !props.isHorizontal
        ? (
          <SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menus} />
          )
        : (
          <KingdeeBaseMenu
            {...(menuProps as any)}
            isHorizontal={props.isHorizontal}
            type={unref(getMenuType)}
            showLogo={unref(getIsShowLogo)}
            mode={unref(getComputedMenuMode as any)}
            items={menus}
          />
          )
    }

    return () => {
      return (
        <>
          {renderHeader()}
          {unref(getUseScroll) ? <ScrollContainer style={unref(getWrapperStyle)}>{() => renderMenu()}</ScrollContainer> : renderMenu()}
        </>
      )
    }
  },
})
</script>

<style lang="less">
@prefix-cls: ~'@{namespace}-kd-layout-menu';
@logo-prefix-cls: ~'@{namespace}-kd-app-logo';

.@{prefix-cls} {
  &-logo {
    height: @header-height;
    padding: 10px 4px 10px 10px;

    img {
      width: @logo-width;
      height: @logo-width;
    }
  }

  &--mobile {
    .@{logo-prefix-cls} {
      &__title {
        opacity: 1;
      }
    }
  }
}
</style>
