import { useMemo, type JSX } from 'react';
import { useMemoizedFn } from 'ahooks';
import { withErrorBoundary } from 'react-error-boundary';
import { ErrorFallback } from '@arcblock/ux/lib/ErrorBoundary';
import { styled, useTheme, deepmerge, ThemeProvider } from '@arcblock/ux/lib/Theme';
import { ResponsiveHeader } from '@arcblock/ux/lib/Header';
import NavMenu, { Products, ProductsType } from '@arcblock/ux/lib/NavMenu';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import { translate } from '@arcblock/ux/lib/Locale/util';
import useBlockletLogo from '@arcblock/ux/lib/hooks/use-blocklet-logo';
import omit from 'lodash/omit';
import isFinite from 'lodash/isFinite';
import type { BoxProps, Breakpoint, Theme } from '@mui/material';
import clsx from 'clsx';
import { getUTMUrl } from '@arcblock/ux/lib/withTracker/libs/utm';

import Icon from '../Icon';
import { mapRecursive, flatRecursive, matchPaths } from '../utils';
import { publicPath, formatBlockletInfo, getLocalizedNavigation } from '../blocklets';
import HeaderAddons from '../common/header-addons';
import { useWalletHiddenTopbar } from '../common/wallet-hidden-topbar';
import { BlockletMetaProps, SessionManagerProps } from '../@types';
import withHideWhenEmbed from '../libs/with-hide-when-embed';

const translations = {
  en: {
    products: 'Products',
  },
  zh: {
    products: '产品',
  },
  'zh-TW': {
    products: '產品',
  },
  ja: {
    products: '製品',
  },
};

// blocklet meta 中的 navigation 数据 => NavMenu 组件的 items
const parseNavigation = (navigation: any) => {
  if (!navigation?.length) {
    return { navItems: [], activeId: null };
  }
  let counter = 1;
  const parseItem = (item: any) => {
    const icon = item.icon ? <Icon icon={item.icon} /> : null;

    // sub menu
    if (item.items) {
      return {
        id: `${counter++}`,
        label: item.title,
        icon,
        children: item.items,
      };
    }
    let props = {};

    // external link
    if (item.link?.startsWith('http') || item.link?.startsWith('//')) {
      props = {
        target: '_blank',
        rel: 'noreferrer',
      };
    }

    return {
      id: `${counter++}`,
      label: (
        <a href={getUTMUrl(item.link, 'header')} {...props}>
          {item.title}
        </a>
      ),
      icon,
      description: item.description,
      link: item.link,
    };
  };
  const navItems = mapRecursive(navigation, parseItem, 'items');
  const flattened = flatRecursive(navItems);
  const matchedIndex = matchPaths(flattened.map((item) => item.link));
  return { navItems, activeId: matchedIndex >= 0 ? flattened[matchedIndex].id : null };
};

type HeaderProps = {
  meta?: BlockletMetaProps;
  addons?: Function | React.ReactNode;
  sessionManagerProps?: SessionManagerProps;
  homeLink?: string | ((brandContent: React.ReactNode) => JSX.Element | null);
  theme?: object;
  hideNavMenu?: boolean;
  bordered?: boolean;
  logo?: React.ReactNode;
  brand?: React.ReactNode;
  brandAddon?: React.ReactNode;
  description?: React.ReactNode;
  children?: React.ReactNode;
  prepend?: React.ReactNode;
  align?: 'left' | 'right';
  maxWidth?: false | Breakpoint;
  showDomainWarningDialog?: boolean;
};

/**
 * 专门用于 (composable) blocklet 的 Header 组件, 解析 blocklet meta 中的数据, 通过组合 UX 中的 Header & NavMenu 组件来渲染
 */
// eslint-disable-next-line no-shadow

function Header({
  meta = {},
  addons = undefined,
  sessionManagerProps = {
    showRole: true,
  },
  homeLink = publicPath,
  theme: themeOverrides = {},
  hideNavMenu = false,
  showDomainWarningDialog = true,
  ...rest
}: HeaderProps & Omit<BoxProps, keyof HeaderProps>) {
  useWalletHiddenTopbar();
  const parentTheme = useTheme();
  const { locale, defaultLocale } = useLocaleContext() || {};
  const t = useMemoizedFn((key, data = {}) => {
    return translate(translations, key, locale, 'en', data);
  });
  const formattedBlocklet = useMemo(() => {
    const blocklet = Object.assign({}, window.blocklet, meta);
    try {
      return formatBlockletInfo(blocklet);
    } catch (e) {
      console.error('Failed to format blocklet info', e, blocklet);
      return blocklet;
    }
  }, [meta]);
  const mergeTheme = useMemo(() => deepmerge(parentTheme, themeOverrides), [parentTheme, themeOverrides]) as Theme;
  const appLogo = useBlockletLogo({
    meta,
    theme: themeOverrides,
  });

  // 显示 Products 导航
  const { productsOrder, productsType } = useMemo<{
    productsOrder: number | null;
    productsType: ProductsType | null;
  }>(() => {
    let { USE_ARCBLOCK_THEME, USE_AIGNE_THEME } = formattedBlocklet;
    USE_ARCBLOCK_THEME = parseInt(USE_ARCBLOCK_THEME, 10);
    USE_AIGNE_THEME = parseInt(USE_AIGNE_THEME, 10);

    if (isFinite(USE_AIGNE_THEME)) {
      return {
        productsOrder: USE_AIGNE_THEME,
        productsType: 'AIGNE',
      };
    }
    if (isFinite(USE_ARCBLOCK_THEME)) {
      return {
        productsOrder: USE_ARCBLOCK_THEME,
        productsType: 'ARCBLOCK',
      };
    }

    return {
      productsOrder: null,
      productsType: null,
    };
  }, [formattedBlocklet]);

  if (!formattedBlocklet.appName) {
    return null;
  }
  const navigation = getLocalizedNavigation({
    navigation: formattedBlocklet?.navigation?.header,
    locale,
    defaultLocale,
  });

  const parsedNavigation = parseNavigation(navigation);
  const { navItems, activeId } = parsedNavigation;

  if (productsType && Number.isInteger(productsOrder)) {
    navItems.splice(productsOrder, 0, {
      label: t('products'),
      // eslint-disable-next-line react/no-unstable-nested-components
      children: () => <Products type={productsType} />,
    });
  }

  // eslint-disable-next-line @typescript-eslint/naming-convention
  const _addons =
    typeof addons === 'function'
      ? (builtInAddons: any) => addons(builtInAddons, { navigation: parsedNavigation })
      : addons;
  const headerAddons = (
    // @ts-ignore
    <HeaderAddons
      formattedBlocklet={formattedBlocklet}
      // @ts-ignore
      addons={_addons}
      // @ts-ignore
      sessionManagerProps={sessionManagerProps}
      showDomainWarningDialog={showDomainWarningDialog}
    />
  );

  return (
    <ThemeProvider theme={mergeTheme}>
      <StyledUxHeader
        // @ts-ignore
        homeLink={homeLink}
        logo={<img src={appLogo} alt="logo" />}
        addons={headerAddons}
        {...omit(rest, ['bordered'])}
        $bordered={rest?.bordered}
        $bgcolor={mergeTheme.palette.background.default}
        className={clsx('blocklet__header', rest.className)}>
        {/* blocklet.yml 没有配置 navigation 时, 则为 children 传入 null, 此时 ResponsiveHeader 会渲染普通的不带 menu 的 Header */}
        {hideNavMenu || !navItems?.length
          ? null
          : ({ isMobile }: { isMobile: boolean }) => (
              // @ts-ignore
              <NavMenu
                mode={isMobile ? 'inline' : 'horizontal'}
                activeId={activeId}
                items={navItems}
                className="header-nav"
                bgColor="transparent"
                textColor={mergeTheme.palette.grey[500]}
                activeTextColor={mergeTheme.palette.text.primary}
              />
            )}
      </StyledUxHeader>
    </ThemeProvider>
  );
}

type StyledUxHeaderProps = {
  $bordered?: boolean;
  $bgcolor?: string;
};

const StyledUxHeader = styled(ResponsiveHeader)<StyledUxHeaderProps>`
  ${({ $bgcolor }) => `background-color: ${$bgcolor || '#fff'};`}
  .header-logo {
    min-width: 44px;
  }
  ${({ $bordered, theme }) => ($bordered ? `border-bottom: 1px solid ${theme.palette.divider};` : '')}
  ${(props) => props.theme.breakpoints.down('md')} {
    .header-logo {
      min-width: 32px;
    }
  }
`;

export default withErrorBoundary(withHideWhenEmbed(Header), {
  FallbackComponent: ErrorFallback,
});
