import { Box } from '@tidbcloud/uikit'
import { NavItemBase, NavItemBaseProps, SubNavItemBase } from '@tidbcloud/uikit/biz'
import { useEffect, useState } from 'react'
import { useHistory, useLocation } from 'react-router-dom'

export interface NavItemProps extends Omit<NavItemBaseProps, 'children' | 'disabled'> {
  path: string
  label: string
  disabled?: ((data: any) => boolean) | boolean
  children?: NavItemProps[]
  onClick?: () => void
  hidden?: boolean
  [key: `data-${string}`]: string
}

interface NavMenuProps {
  navList: NavItemProps[]
  defaultOpenedSub?: boolean
}

interface NavItemMenuProps extends NavItemProps {
  defaultOpenedSub?: boolean
}

const matchesNavPath = (pathname: string, path: string) => pathname === path || pathname.startsWith(`${path}/`)

const NavItemMenu = (nav: NavItemMenuProps) => {
  const { children, defaultOpenedSub, label, leftSection, onClick, disabled, path, ...rest } = nav
  const history = useHistory()
  const { pathname } = useLocation()
  const hasChildren = children && children.length
  const defaultOpened =
    nav.children?.some((ch) => {
      return matchesNavPath(pathname, ch.path)
    }) || defaultOpenedSub
  const [opened, setOpened] = useState(defaultOpened)

  useEffect(() => {
    if (hasChildren && children?.some((ch) => matchesNavPath(pathname, ch.path))) {
      setOpened(true)
    }
  }, [pathname, hasChildren, children])

  return (
    <Box>
      <NavItemBase
        label={label}
        leftSection={leftSection}
        active={hasChildren ? false : matchesNavPath(pathname, path)}
        opened={opened}
        onClick={() => {
          onClick?.()
          if (!hasChildren) {
            history.push(path)
          }
        }}
        disabled={typeof disabled === 'boolean' ? disabled : undefined}
        onChange={(opened) => {
          setOpened(opened)
        }}
        {...rest}
      >
        {nav.children?.map((ch) => {
          const { path, label, leftSection, onClick, disabled, children: _children, ...rest } = ch

          if (ch.hidden) {
            return null
          }
          return (
            <SubNavItemBase
              key={path}
              label={label}
              active={matchesNavPath(pathname, path)}
              onClick={() => {
                onClick?.()
                history.push(path)
              }}
              disabled={typeof disabled === 'boolean' ? disabled : undefined}
              {...rest}
            />
          )
        })}
      </NavItemBase>
    </Box>
  )
}

export const NavMenu = ({ navList, defaultOpenedSub }: NavMenuProps) => {
  const links = navList.map((nav, index) => {
    if (nav.hidden) {
      return null
    }
    return <NavItemMenu key={nav.path + index.toString()} {...nav} defaultOpenedSub={defaultOpenedSub} />
  })

  return <>{links}</>
}
