import { useEffect, useMemo } from 'react';
import { useLocation, matchPath, type Location } from 'react-router-dom';
import Helmet from 'react-helmet';
import { Container, Box, type SxProps } from '@mui/material';
import clsx from 'clsx';
import { OpenInFull as OpenInFullIcon, CloseFullscreen as CloseFullscreenIcon } from '@mui/icons-material';
import DashboardLegacy from '../dashboard-legacy';
import { ResponsiveHeader } from '../../Header';
import NavMenu from '../../NavMenu';
import Footer, { type FooterProps } from '../../Footer';
import Sidebar, { type LinkItem } from './sidebar';
import { styled, useTheme } from '../../Theme';
import { Link } from './external-link';
import { FullPageProvider, useFullPage } from './full-page';
import { NavMenuProps } from '../../NavMenu/nav-menu';
import { type DashboardProps as DashboardLegacyProps } from '../dashboard-legacy';

// 监听 location 变化并关闭 header 中的 menu (确保 drawer - disablePortal:false, keepMounted:true)
// 直接监听 menu 中 link 点击来触发 closeMenu 会有问题 (Suspense & lazy)
function NavMenuWrapper({ closeMenu, ...rest }: { closeMenu: () => void } & NavMenuProps) {
  const location = useLocation();
  useEffect(() => {
    closeMenu();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [location]);
  return <NavMenu {...rest} />;
}

function formatLinks(links: LinkItem[], location: Location): LinkItem[] {
  return links.map((link) => {
    if (link.children?.length) {
      return {
        ...link,
        label: link.title,
        children: formatLinks(link.children, location),
      };
    }
    return {
      ...link,
      label: (
        <Link to={link.url} external={link.external}>
          {link.title}
        </Link>
      ),
      // external = true 时 active 状态由传入 links 的调用方决定 (适用于 blocklet ui dashboard 的情况)
      active: link.external ? link.active : !!matchPath({ path: link.url, end: false }, location.pathname),
    };
  });
}

export interface DashboardProps extends React.HTMLAttributes<HTMLDivElement> {
  title?: string;
  headerProps?: object;
  /** 支持分组, links item 如果是数组, 则视为一个 group */
  links?: LinkItem[];
  sidebarWidth?: number;
  fullWidth?: false | true;
  /** sidenav 稠密一些的布局, 纵向空间占用较少, 默认为 auto, 当 links 个数 > 8 时自动启用 */
  dense?: 'auto' | boolean;
  footerProps?: FooterProps;
  sx?: SxProps;
  /** 是否隐藏 html title, 默认不隐藏, 避免重复导致 html title 失效 */
  hideHtmlTitle?: boolean;
}

function Dashboard({
  title = 'Home',
  headerProps = {},
  links = [],
  sidebarWidth = 120,
  fullWidth = false,
  dense = 'auto',
  footerProps = {},
  sx = {},
  children,
  hideHtmlTitle = false,
  ...rest
}: DashboardProps) {
  const theme = useTheme();
  const { inFullPage, showToggleButton, headerVisible, footerVisible, sidebarVisible, toggleFullPage } = useFullPage();
  const location = useLocation();
  const navItems = useMemo(() => formatLinks(links, location), [location, links]);
  const isGroupedMode = navItems.some((item) => !!item.children?.length);
  // 一级菜单数量 > 8 或都分组模式, 都启用 dense 布局
  const _dense = dense === 'auto' ? navItems.length >= 8 || isGroupedMode : dense;
  const classes = clsx('dashboard', { 'dashboard-dense': _dense }, rest.className);
  const defaultHomeLink = (content: React.ReactNode) => <Link to={window.blocklet?.prefix || '/'}>{content}</Link>;
  const _headerProps = {
    homeLink: defaultHomeLink,
    ...headerProps,
  };

  useEffect(() => {
    const { searchParams } = new URL(window.location.href);
    if (searchParams.get('inviter')) {
      window.localStorage.setItem('inviter', searchParams.get('inviter')!);
    }
  }, []);

  return (
    <Wrapper sx={sx} {...rest} className={classes} sidebarWidth={sidebarWidth}>
      {!hideHtmlTitle && <Helmet title={title} key={title} />}
      {headerVisible && (
        <StyledUxHeader {..._headerProps} className="dashboard-header">
          {links?.length
            ? ({ isMobile, closeMenu }) => {
                if (isMobile) {
                  return (
                    <NavMenuWrapper
                      mode="inline"
                      items={navItems}
                      closeMenu={closeMenu}
                      bgColor="transparent"
                      activeTextColor={theme.palette.primary.main}
                    />
                  );
                }
                return null;
              }
            : null}
        </StyledUxHeader>
      )}
      <Box
        className="dashboard-body"
        sx={{
          display: 'flex',
        }}>
        {!!links?.length && sidebarVisible && (
          <Box
            className="dashboard-sidebar"
            sx={{
              display: {
                xs: 'none',
                md: 'block',
              },
            }}>
            {_dense ? (
              <Sidebar links={links} dense={_dense} />
            ) : (
              <Box className="dashboard-sidebar-container">
                <Sidebar links={links} dense={_dense} />
              </Box>
            )}
          </Box>
        )}
        <Box className="dashboard-main" id="arc__dashboard-main">
          {showToggleButton && (
            <Box
              sx={{
                position: 'absolute',
                top: 4,
                right: 4,
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center',
                width: 24,
                height: 24,
                color: '#fff',
                bgcolor: 'rgba(158,158,158, 0.6);',
                borderRadius: 1,
                cursor: 'pointer',
              }}
              onClick={toggleFullPage}>
              {inFullPage ? (
                <CloseFullscreenIcon style={{ fontSize: 18 }} />
              ) : (
                <OpenInFullIcon style={{ fontSize: 18 }} />
              )}
            </Box>
          )}
          <Container className="dashboard-content" id="arc__dashboard-content" {...(fullWidth && { maxWidth: false })}>
            {children}
          </Container>
          {footerVisible && <Footer {...{ dark: theme.palette.mode === 'dark', ...footerProps }} />}
        </Box>
      </Box>
    </Wrapper>
  );
}

type WrapperProps = React.HTMLAttributes<HTMLDivElement> & { sidebarWidth: number };

const Wrapper = styled(Box)<WrapperProps>`
  &.dashboard {
    display: flex;
    flex-direction: column;
    height: 100vh;
    background-color: ${({ theme }) => theme.palette.background.default};
  }
  .dashboard-body {
    overflow: hidden;
    flex: 1;
  }
  .dashboard-sidebar {
    box-sizing: border-box;
    flex: 0 0 auto;
    width: ${(props) => props.sidebarWidth}px;
    overflow: hidden;
    &:hover {
      overflow-y: auto;
    }
  }
  .dashboard-sidebar-container {
    width: ${(props) => props.sidebarWidth}px;
  }
  .dashboard-main {
    display: flex;
    flex-direction: column;
    overflow: auto;
    flex: 1;
    position: relative;
  }
  .dashboard-content {
    flex: 1;
  }
  &.dashboard-dense {
    .dashboard-header {
      border-bottom: 1px solid;
      border-color: ${({ theme }) => theme.palette.divider};
    }
    .dashboard-sidebar {
      width: 256px;
      border-right: 1px solid;
      border-color: ${({ theme }) => theme.palette.divider};
    }
  }
  ${(props) => props.theme.breakpoints.up('md')} {
    .header-logo {
      display: flex;
      justify-content: center;
    }
    &.dashboard-dense {
      .header-logo {
        /* dense = true 时 logo 与 sidenav icons 不需要对齐 */
        width: auto;
      }
    }
  }
`;

const StyledUxHeader = styled(ResponsiveHeader)`
  .header-container {
    max-width: 100%;
  }
`;

// 兼容旧版 dashboard
export default function DashboardWrapper<T extends boolean = true>({
  legacy = true as T,
  ...rest
}: T extends true ? { legacy?: T } & DashboardLegacyProps : { legacy?: T } & DashboardProps) {
  if (legacy) {
    return <DashboardLegacy {...(rest as unknown as DashboardLegacyProps)} />;
  }
  return (
    <FullPageProvider>
      <Dashboard {...rest} />
    </FullPageProvider>
  );
}
