import React, { useContext, useEffect } from 'react';
import { ConfigProvider } from 'antd';
import propTypes from 'prop-types';
import Icon from '@ant-design/icons';
import warning from 'warning';
import SlideMenu from '../components/SlideMenu';
import WrapContent from '@wisdom-utils/components/lib/AppLayout/layouts/WrapContent';
import Header from '@wisdom-utils/components/lib/AppLayout/layouts/Header';
import Footer from '@wisdom-utils/components/lib/AppLayout/layouts/Footer';
import TopNavHeader from '@wisdom-utils/components/lib/AppLayout/components/TopNavHeader';
import PageContainer from '@wisdom-utils/components/lib/AppLayout/components/PageContainer';
import { helpers } from '@wisdom-utils/utils';
import { getBreadcrumbProps } from '@wisdom-utils/components/lib/AppLayout/layouts/utils/getBreadcrumbProps';
import getMenuData from '@wisdom-utils/components/lib/AppLayout/layouts/utils/getMenuData';
import { findPathByLeafId } from '@wisdom-utils/components/lib/AppLayout/helpers';
const { renderRoutes } = helpers;
import { MinPanel } from '@wisdom-utils/components/lib/AppLayout/components/SliderPanel';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import RouteContext from '@wisdom-utils/components/lib/AppLayout/layouts/RouteContext';
import { getPageTitleInfo } from '@wisdom-utils/components/lib/AppLayout/layouts/getPageTitle';
import omit from 'omit.js';
import classNames from 'classnames';
import useDocumentTitle from '@wisdom-utils/components/lib/AppLayout/layouts/hooks/useDocumentTitle';
import defaultSettings from '@wisdom-utils/components/lib/AppLayout/layouts/defaultSettings';
import isBrowser from '@wisdom-utils/components/lib/AppLayout/layouts/utils/isBrowser';
const homeSvg = () => (
  <svg
    t="1631169883330"
    className="icon"
    viewBox="0 0 1024 1024"
    version="1.1"
    xmlns="http://www.w3.org/2000/svg"
    p-id="2203"
    width="20"
    height="20"
  >
    <path
      d="M423.9 487H221.7c-34.9 0-63.4-28.4-63.4-63.4V221.5c0-34.9 28.4-63.4 63.4-63.4h202.2c34.9 0 63.4 28.4 63.4 63.4v202.2c-0.1 34.9-28.5 63.3-63.4 63.3z m0-63.3v31.7-31.7zM221.7 221.5v202.2h202.1l0.1-202.2H221.7zM803.1 487H600.9c-34.9 0-63.4-28.4-63.4-63.4V221.5c0-34.9 28.4-63.4 63.4-63.4h202.2c34.9 0 63.4 28.4 63.4 63.4v202.2c0 34.9-28.5 63.3-63.4 63.3z m0-63.3v31.7-31.7zM600.9 221.5v202.2H803l0.1-202.2H600.9zM423.9 865.8H221.7c-34.9 0-63.4-28.4-63.4-63.4V600.3c0-34.9 28.4-63.4 63.4-63.4h202.2c34.9 0 63.4 28.4 63.4 63.4v202.2c-0.1 34.9-28.5 63.3-63.4 63.3z m0-63.3v31.7-31.7zM221.7 600.3v202.2h202.1l0.1-202.2H221.7zM736.9 865.8h-69.7c-71.4 0-129.6-58.1-129.6-129.6v-69.7c0-71.4 58.1-129.6 129.6-129.6h69.7c71.4 0 129.6 58.1 129.6 129.6v69.7c0 71.5-58.2 129.6-129.6 129.6z m-69.8-265.5c-36.5 0-66.2 29.7-66.2 66.2v69.7c0 36.5 29.7 66.2 66.2 66.2h69.7c36.5 0 66.2-29.7 66.2-66.2v-69.7c0-36.5-29.7-66.2-66.2-66.2h-69.7z"
      fill="#B2B2B2"
    />
  </svg>
);
const HomeIcon = (props) => <Icon component={homeSvg} {...props} style={{ marginRight: '0px' }} />;

const defaultPageTitleRender = (pageProps, props) => {
  const { pageTitleRender } = props;
  const pageTitleInfo = getPageTitleInfo(pageProps);
  if (pageTitleRender === false) {
    return {
      title: props.title || '',
      id: '',
      pageName: '',
    };
  }

  if (pageTitleRender) {
    const title = pageTitleRender(pageProps, pageTitleInfo.title, pageTitleInfo);
    if (typeof title === 'string') {
      return {
        ...pageTitleInfo,
        title,
      };
    }
    warning(typeof title === 'string', 'layout: renderPageTitle return value should be a string');
  }
  return pageTitleInfo;
};
const headerRender = (props) => {
  if (props.headerRender === false) {
    return null;
  }
  return <Header {...props} />;
};
const footerRender = (props) => {
  if (props.footerRender === false) {
    return null;
  }

  if (props.footerRender) {
    return props.footerRender({ ...props }, <Footer />);
  }
  return null;
};

const renderSiderMenu = (props) => {
  const { menuRender } = props;
  if (menuRender === false) {
    return null;
  }
  const defaultDom = <SlideMenu {...props} />;

  if (menuRender) {
    return menuRender(props, defaultDom);
  }
  return defaultDom;   
};

const getPaddingLeft = (hasLeftPadding, collapsed, siderWidth) => {
  if (hasLeftPadding) {
    return collapsed ? 48 : siderWidth;
  }
  return 0;
};

const BasicLayout = (props) => {
  const {
    children,
    route,
    style,
    contentStyle,
    siderWidth = 80,
    location = { pathname: '/' },
    menu,
    handerMapContentRender,
    subMenuItemRender,
    menuItemRender,
    menuHeaderRender,
    currentMenuIndex,
    onMenuHeaderClick,
    onMenuPanelItemClick,
    onPageChange,
    disableContentMargin,
    isChildrenLayout: propsIsChildrenLayout,
    menuDataRender,
    formatMessage,
  } = props || {};

  const context = useContext(ConfigProvider.ConfigContext);
  const prefixCls = props.prefixCls ?? context.getPrefixCls();
  const [tabActiveKey, setTabActiveKey] = React.useState('1');
  const [selectedKey, setSelectedKey] = React.useState([]);
  const [subRoutes, setSubRoutes] = React.useState([]);
  const [currentRoute, setCurrentRoute] = React.useState({});
  const [selectIndex, setSelectIndex] = React.useState(-1);
  const [visible, setVisible] = React.useState(false);
  const [activeMenu, setActiveMenu] = useMergedState(() => 0, {
    value: currentMenuIndex,
    onChange: onMenuPanelItemClick,
  });
  const [collapsed, onCollapse] = useMergedState(() => false, {
    value: props.collapsed,
    onChange: props.onCollapse,
  });
  const menuInfoData = React.useMemo(
    () => getMenuData(route?.routes || [], menu, formatMessage, menuDataRender),
    [formatMessage, menu, menuDataRender, route?.routes],
  );

  const { breadcrumb = {}, breadcrumbMap, menuData = [] } = menuInfoData || {};

  const defaultProps = omit(
    {
      prefixCls,
      ...props,
      siderWidth,
      formatMessage,
      breadcrumb,
    },
    ['className', 'style', 'breadcrumbRender'],
  );

  const pageTitleInfo = defaultPageTitleRender(
    {
      pathname: location.pathname,
      ...defaultProps,
      breadcrumbMap,
    },
    props,
  );

  const breadcrumbProps = getBreadcrumbProps(
    {
      ...defaultProps,
      breadcrumbRender: props.breadcrumbRender,
      breadcrumbMap,
    },
    props,
  );

  const onMenuClick = (current, routes, activeIndex = []) => {
    setTabActiveKey(current.path);
    if (current.routes) {
      setSelectedKey([current.routes[0].href]);
      setSelectIndex(activeIndex);
    }
    setSubRoutes(routes);
  };

  const _onMenuHeaderClick = () => {
    onMenuHeaderClick && onMenuHeaderClick();
    setVisible(!visible);
  };

  const siderMenuDom = renderSiderMenu(
    Object.assign(
      {},
      {
        ...defaultProps,
        collapsed,
        onCollapse,
        route: currentRoute,
        active: selectIndex,
        onActiveChange: setSelectIndex,
        menu,
        menuItemRender,
        menuHeaderRender,
        onMenuClick,
        onMenuHeaderClick: _onMenuHeaderClick,
      },
    ),
  );

  const headerDom = headerRender({
    ...defaultProps,
    hasSiderMenu: !!siderMenuDom,
    collapsed,
    onCollapse,
  });

  const footerDom = footerRender({
    collapsed,
    ...defaultProps,
  });

  const hasLeftPadding = true;

  const { isChildrenLayout: contextIsChildrenLayout } = useContext(RouteContext);

  const isChildrenLayout =
    propsIsChildrenLayout !== undefined ? propsIsChildrenLayout : contextIsChildrenLayout;

  const leftSiderWidth = getPaddingLeft(!!hasLeftPadding, collapsed, siderWidth);

  const genLayoutStyle = {
    position: 'relative',
  };

  if (isChildrenLayout || (contentStyle && contentStyle.minHeight)) {
    genLayoutStyle.minHeight = 0;
  }
  const baseClassName = `${prefixCls}-basic-layout`;
  const contentClassName = classNames(`${baseClassName}-content`, {
    [`${baseClassName}-has-header`]: headerDom,
    [`${baseClassName}-content-disable-margin`]: disableContentMargin,
  });

  const [hasFooterToolbar, setHasFooterToolbar] = React.useState(false);

  useEffect(() => {
    const newRoutes =
      (route &&
        route.routes &&
        Array.isArray(route.routes) &&
        route.routes.filter((item) => !item.hideInMenu)[currentMenuIndex]) ||
      {};
    if (!_.isEqual(currentRoute, newRoutes)) {
      // setCurrentRoute({});
      setSelectIndex(-1);
      setCurrentRoute(newRoutes);
    }
  }, [route, currentMenuIndex]);

  useEffect(() => {
    const initSelectRoute = findPathByLeafId(
      `${(props.location && props.location.pathname) || ''}`,
      [currentRoute],
      '',
      'path',
      true,
    );

    const parentMenuName =
      initSelectRoute && initSelectRoute.parent && initSelectRoute.parent.label;
    if (parentMenuName) {
      let currentChildrenRoute = currentRoute.routes.find((item) => item.name === parentMenuName);
      if (!currentChildrenRoute) {
        currentChildrenRoute = initSelectRoute;
      }
      let childrenName = currentChildrenRoute ? currentChildrenRoute.name : parentMenuName;
      if (currentChildrenRoute.routes) {
        const active = currentChildrenRoute.routes.find(
          (item) => item.name === initSelectRoute.name,
        );
        setTabActiveKey(active.path);
      } else {
        setTabActiveKey(currentChildrenRoute.path);
      }
      const initSelectIndex = currentRoute.routes.findIndex((item) => item.name === childrenName);
      setSelectIndex(initSelectIndex);
      currentChildrenRoute && currentChildrenRoute.routes
        ? setSubRoutes(currentChildrenRoute.routes)
        : setSubRoutes([currentChildrenRoute]);
    } else {
      let url =
        props.config && props.config.hasOwnProperty('get') && props.config.get('homepage')
          ? _.isString(props.config.get('homepage'))
            ? props.config.get('homepage')
            : props.config.get('homepage.url')
          : '';
      if (!props.config.get('home')) {
        url = `civweb4/${url.replace(/^\//, '').replace(/^civweb4\//, '')}`;
      }
      setSelectIndex(-1);
      setSubRoutes([
        {
          icon: <HomeIcon />,
          path: `/${url}`,
          name: '首页',
        },
      ]);
    }
  }, []);

  useEffect(() => {
    window.share &&
      window.share.event &&
      window.share.event.on(
        'event:updateCurrentChildrenRoutes',
        ({ currentPath, currentRoute, selectedIndex }) => {
          currentRoute && currentRoute.parent && currentRoute.parent.routes
            ? setSubRoutes(currentRoute.parent.routes)
            : !currentRoute.parent
            ? setSubRoutes(currentRoute.routes)
            : setSubRoutes([currentRoute]);
          setSelectIndex(selectedIndex);
          setTabActiveKey(currentPath);
        },
      );

    window.share &&
      window.share.event &&
      window.share.event.on('event:favitor', ({ icon, name, path }) => {
        setSubRoutes([
          {
            icon: <HomeIcon />,
            path: path,
            name: name,
          },
        ]);
      });

    window.share &&
      window.share.event &&
      window.share.event.on('goHome', (url) => {
        setSubRoutes([
          {
            icon: <HomeIcon />,
            path: url,
            name: '首页',
          },
        ]);
        setTabActiveKey(url);
        window.history.pushState(null, '', `/civbase${url}`);
      });
    return () => {
      window.share &&
        window.share.event &&
        window.share.event.removeAllListeners('event:updateCurrentChildrenRoutes');
      window.share && window.share.event && window.share.event.removeAllListeners('event:favitor');
      window.share && window.share.event && window.share.event.removeAllListeners('goHome');
    };
  }, []);

  useEffect(() => {
    if (selectIndex !== -1 && currentRoute && currentRoute.hasOwnProperty('routes')) {
      const routes = currentRoute.routes[selectIndex];
      if (routes) {
        if (routes && routes.routes) {
          const route =
            routes &&
            routes.routes &&
            routes.routes.find(
              (item) => item.path === decodeURI(window.location.pathname.replace('/civbase', '')),
            );
          if (route && route.path) {
            setTabActiveKey(route.path);
          }
        }
      }
    }
    onPageChange && onPageChange(props.location);
  }, [props.location, location.pathname.search]);

  useDocumentTitle(pageTitleInfo, props.title || false);

  return (
    <RouteContext.Provider
      value={{
        collapsed,
        currentRoute,
        isChildrenLayout: true,
        title: pageTitleInfo.pageName,
        hasSiderMenu: !!siderMenuDom,
        hasHeader: !!headerDom,
        siderWidth: leftSiderWidth,
        hasFooter: !!footerDom,
        hasFooterToolbar,
        setHasFooterToolbar,
        pageTitleInfo,
      }}
    >
      <div className={`${prefixCls}-basic-layout`}>
        <div className={`${prefixCls}-basic-layout-has-slider`} style={{ minHeight: '100%' }}>
          {siderMenuDom}
          <div className={`${prefixCls}-layout`} style={{ width: 'calc(100% - 80px)' }}>
            <MinPanel
              visible={visible}
              keyboard
              data={route.routes || []}
              onClose={() => setVisible(false)}
              currentMenuIndex={activeMenu}
              onChange={(index) => setActiveMenu(index)}
            />

            <WrapContent
              isChildrenLayout={isChildrenLayout}
              className={contentClassName}
              style={contentStyle}
            >
              <div className={`${prefixCls}-page-container-wrap`}>{headerDom}</div>
              {subMenuItemRender ? (
                subMenuItemRender(props)
              ) : (
                <TopNavHeader
                  {...props}
                  childrenRoutes={subRoutes}
                  tabActiveKey={tabActiveKey}
                  selectedKey={selectedKey}
                  onTabChange={setTabActiveKey}
                  onHandlerSubmenu={setSelectedKey}
                />
              )}
              <PageContainer style={{ paddingTop: '0px', height: '100%' }}>
                {renderRoutes(prefixCls, route.routes, props)}
                {handerMapContentRender && handerMapContentRender(props)}
                {children}
              </PageContainer>
            </WrapContent>
            {footerDom}
          </div>
        </div>
      </div>
    </RouteContext.Provider>
  );
};

BasicLayout.propTypes = {
  logo: propTypes.node || propTypes.string,
  config: propTypes.object,
  onPageChange: propTypes.func,
  collapsed: propTypes.bool,
  onCollapse: propTypes.func,
  isChildrenLayout: propTypes.bool,
  footerRender: propTypes.func || propTypes.bool,
  className: propTypes.string,
  contentStyle: propTypes.object,
  disableContentMargin: propTypes.bool,
  waterMarkProps: propTypes.object,
  ErrorBoundary: propTypes.any,
  pageTitleRender: propTypes.func || propTypes.bool,
  menuRender: propTypes.func || propTypes.bool,
  menuDataRender: propTypes.func || propTypes.bool,
  breadcrumbRender: propTypes.func || propTypes.bool,
  itemRender: propTypes.node,
  headerRender: propTypes.func || propTypes.bool,
  breadcrumbProps: propTypes.object,
};

BasicLayout.defaultProps = {
  ...defaultSettings,
  location: isBrowser() ? window.location : undefined,
};

export default BasicLayout;
