import {
  Refine,
  useTranslate,
  useLogout,
  useTitle,
  CanAccess,
  ITreeMenu,
  useIsExistAuthentication,
  useRouterContext,
  useMenu,
  useRefineContext,
} from '@pankod/refine-core'
import {
  Layout,
  AntdLayout,
  Grid,
  Icons,
  Menu,
  Title as DefaultTitle,
} from '@pankod/refine-antd'
import routerProvider from '@pankod/refine-react-router-v6'
import dataProvider from '@pankod/refine-simple-rest'
import { PostList } from './pages/posts'
const API_URL = 'https://api.fake-rest.refine.dev'
export type SiderRenderProps = {
  items: JSX.Element[]
  logout: React.ReactNode
  dashboard: React.ReactNode
}
export type RefineLayoutSiderProps = {
  render?: (props: SiderRenderProps) => React.ReactNode
}
const { DashboardOutlined, LogoutOutlined, UnorderedListOutlined } = Icons
const CustomSider: React.FC<RefineLayoutSiderProps> = ({ render }) => {
  const [collapsed, setCollapsed] = useState<boolean>(false)
  const isExistAuthentication = useIsExistAuthentication()
  const { Link } = useRouterContext()
  const { mutate: mutateLogout } = useLogout()
  const Title = useTitle()
  const translate = useTranslate()
  const { menuItems, selectedKey, defaultOpenKeys } = useMenu()
  const breakpoint = Grid.useBreakpoint()
  const { hasDashboard } = useRefineContext()
  const isMobile = typeof breakpoint.lg === 'undefined' ? false : !breakpoint.lg
  const RenderToTitle = Title ?? DefaultTitle
  const renderTreeView = (tree: ITreeMenu[], selectedKey: string) => {
    return tree.map((item: ITreeMenu) => {
      const { icon, label, route, name, children, parentName } = item
      if (children.length > 0) {
        return (
          <CanAccess
            key={route}
            resource={name.toLowerCase()}
            action="list"
            params={{
              resource: item,
            }}
          >
            <SubMenu
              key={route}
              icon={icon ?? <UnorderedListOutlined />}
              title={label}
            >
              {renderTreeView(children, selectedKey)}
            </SubMenu>
          </CanAccess>
        )
      }
      const isSelected = route === selectedKey
      const isRoute = !(parentName !== undefined && children.length === 0)
      return (
        <CanAccess
          key={route}
          resource={name.toLowerCase()}
          action="list"
          params={{
            resource: item,
          }}
        >
          <Menu.Item
            key={route}
            style={{
              fontWeight: isSelected ? 'bold' : 'normal',
            }}
            icon={icon ?? (isRoute && <UnorderedListOutlined />)}
          >
            <Link to={route}>{label}</Link>
            {!collapsed && isSelected && (
              <div className="ant-menu-tree-arrow" />
            )}
          </Menu.Item>
        </CanAccess>
      )
    })
  }
  const logout = isExistAuthentication ? (
    <Menu.Item
      key="logout"
      onClick={() => mutateLogout()}
      icon={<LogoutOutlined />}
    >
      {translate('buttons.logout', 'Logout')}
    </Menu.Item>
  ) : null
  const dashboard = hasDashboard ? (
    <Menu.Item
      key="dashboard"
      style={{
        fontWeight: selectedKey === '/' ? 'bold' : 'normal',
      }}
      icon={<DashboardOutlined />}
    >
      <Link to="/">{translate('dashboard.title', 'Dashboard')}</Link>
      {!collapsed && selectedKey === '/' && (
        <div className="ant-menu-tree-arrow" />
      )}
    </Menu.Item>
  ) : null
  const items = renderTreeView(menuItems, selectedKey)
  const renderSider = () => {
    if (render) {
      return render({
        dashboard,
        items,
        logout,
      })
    }
    return (
      <>
        {dashboard}
        {items}
        {logout}
      </>
    )
  }
  const antLayoutSider: CSSProperties = {
    position: 'relative',
  }
  const antLayoutSiderMobile: CSSProperties = {
    position: 'fixed',
    height: '100vh',
    zIndex: 999,
  }
  return (
    <AntdLayout.Sider
      collapsible
      collapsed={collapsed}
      onCollapse={(collapsed: boolean): void => setCollapsed(collapsed)}
      collapsedWidth={isMobile ? 0 : 80}
      breakpoint="lg"
      style={isMobile ? antLayoutSiderMobile : antLayoutSider}
    >
      <RenderToTitle collapsed={collapsed} />
      <Menu
        selectedKeys={[selectedKey]}
        defaultOpenKeys={defaultOpenKeys}
        mode="inline"
        onClick={() => {
          if (!breakpoint.lg) {
            setCollapsed(true)
          }
        }}
      >
        {renderSider()}
      </Menu>
    </AntdLayout.Sider>
  )
}
const App: React.FC = () => {
  return (
    <Refine
      routerProvider={routerProvider}
      dataProvider={dataProvider(API_URL)}
      Layout={Layout}
      Sider={CustomSider}
      resources={[
        {
          name: 'posts',
          list: PostList,
        },
      ]}
    />
  )
}