import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';

import {
  Anchor,
  Button,
  Popover,
  Radio,
  Result,
  Spin,
} from 'antd';
import classNames from 'classnames';
import { dom } from 'kit_utils';
import _ from 'lodash';
import { connect } from 'react-redux';
import { renderRoutes } from 'react-router-config';
import { useHistory } from 'react-router-dom';
import { useMountedState } from 'react-use';

import {
  LeftOutlined,
  MenuFoldOutlined,
} from '@ant-design/icons';
import ProLayout from '@ant-design/pro-layout';
import { getMatchMenu } from '@umijs/route-utils';

import pkg from '../../package.json';
import RightContent from '../components/GlobalHeader/RightContent';
import { Panel } from '../components/SliderPanel';
import { actionCreators } from '../containers/App/store';
import Authorized from '../utils/Authorized';
import isProd from '../utils/env';
import {
  findPathByLeafId,
  getBaseName,
} from '../utils/utils';
import SecurityLayout from './SecurityLayout';
import Site from './Site';
import styles from './UserLayout.less';

const baseURI = isProd
  ? window.location.origin
  : `http://${window.location.hostname}:3020`;
const optionsWith = [
  { label: '按站点', value: 'site' },
  { label: '按城市', value: 'city' },
];
const noMatch = (
  <Result
    status={403}
    title="403"
    subTitle="Sorry, you are not authorized to access this page."
    extra={<Button type="primary">Go Login</Button>}
  />
);

const renderIcon = (icon, size) => {
  const transformIcon = () => {
    return icon.replace(/\s*/g, '')
  }
  return (
    <img
      src={`${baseURI}/civweb4/${transformIcon()}`}
      style={{ width: `${size}px`, height: `${size}px`, opacity: '0.8' }}
    />
  );
};
const menuExtraRender = currentRoutes => {
  const [toggleSystem, setToggleSystem] = useState(false);
  return {
    render: ({ collapsed }) => {

      if (currentRoutes) {
        return (
          <>
            <Spin spinning={ currentRoutes.extData && !currentRoutes.extData.icon}>
            {
              currentRoutes.extData && currentRoutes.extData.icon && (
                <a
                style={{ display: 'flex', alignItems: 'center' }}
                onClick={() => setToggleSystem(!toggleSystem)}
              >
               <img
                 src={`${baseURI}/civweb4/${currentRoutes &&
                   currentRoutes.extData &&
                   currentRoutes.extData.icon}`}
                 style={{ width: '20px', height: '20px' }}
               />

               <span
                 style={{
                   margin: '0 2px 0 7px',
                   textOverflow: 'ellipsis',
                   overflow: 'hidden',
                   whiteSpace: 'nowrap',
                   color: 'rgba(255, 255, 255, 0.65)',
                   fontSize: '14px',
                 }}
               >
                 {currentRoutes && currentRoutes.name}
               </span>
               <MenuFoldOutlined style={{ color: '#888', marginLeft: '10px' }} />
             </a>
              )

            }
            </Spin>


          </>
        );
      }
      return null;
    },
    toggleSystem,
    onClose: () => setToggleSystem(!toggleSystem),
  };
};
const HOT = ['HOT', '县', '市', 'New'];
const StationsItem = (item, action) => {
  const changeGroup = (event, data) => {
    action.changeGroup && action.changeGroup(event, data);
  };
  return (
    <li
      key={item.groupID}
      style={{ marginRight: `${item.style.marginRight}px` }}
    >
      <a
        className={classNames(styles.city_select, styles.showTip)}
        title={item.city}
        index={item.promoteIndex}
        style={{ fontSize: '13px' }}
        onClick={event => changeGroup(event, item)}
      >
        {item.groupName}
        {item.promoteTip && HOT.includes(item.promoteTip) && (
          <div imgType={item.promoteTip}>{item.promoteTip}</div>
        )}
      </a>
    </li>
  );
};

const Stations = props => {
  const data = props.data.stations;
  const [targetOffset, setTargetOffset] = useState(undefined);
  const cityPane = useRef(null);
  const cityContent = useRef(null);
  const [defaultTab, setDefaultTab] = useState('site');
  useEffect(() => {
    setTargetOffset(cityPane.current.clientHeight / 2);
  }, []);

  const handleClick = (event, link) => {
    event.preventDefault();
  };

  const handleTabChange = event => {
    setDefaultTab(event.target.value);
  };
  return (
    <>
      <div className={styles.focusStations}>
        <ul>
          {Array.isArray(data)
            ? data.map(item => {
                return StationsItem(item, props.action);
              })
            : null}
        </ul>
      </div>
      <Radio.Group
        options={optionsWith}
        optionType="button"
        buttonStyle="solid"
        size="small"
        value={defaultTab}
        onChange={handleTabChange}
        style={{ marginTop: '6px' }}
      />
      <div style={{ maxWidth: '520px', position: 'relative' }}>
        {defaultTab === 'site' ? (
          <div
            className={classNames(styles.city_pane, styles.station_container)}
            ref={cityPane}
          >
            <Anchor
              affix={false}
              onClick={handleClick}
              targetOffset={targetOffset}
              getContainer={() => cityContent.current}
            >
              <ul className={styles.py}>{props.data.siteCityList.letters}</ul>
              <div
                className={styles.cityContent}
                style={{ height: '335px' }}
                ref={cityContent}
              >
                {props.data.siteCityList.content}
              </div>
            </Anchor>
          </div>
        ) : (
          <div className="city_pane city_container">
            {props.data.citySelector}
          </div>
        )}
        <Spin spinning={props.loading} tip="加载中"/>
      </div>
    </>
  );
};

const renderTitle = (
  title,
  action,
  data,
  loading,
  setLoading,
  collapsed,
  fixedHeader,
) => {
  const [visible, setVisible] = useState(false);
  const header = document.querySelector('.ant-pro-fixed-header');
  let marginLeft = '148px';
  const DEFAULT_MIXIN_WIDTH = 48;
  if (header && fixedHeader) {
    const documentWidth = document.body.clientWidth;
    if (documentWidth === header.offsetWidth && !collapsed) {
      marginLeft = '148px';
    } else {
      const deltWidth = document.body.clientWidth - header.offsetWidth;
      marginLeft = collapsed
        ? '0px'
        : deltWidth === DEFAULT_MIXIN_WIDTH
        ? `100px`
        : `${deltWidth}px`;
    }
  }
  return {
    render: (
      <>
        <span
          className={styles['header-title']}
          style={{ marginLeft: marginLeft }}
        >
          {title}
        </span>
        <div className={styles.cityContent}>
          <Popover
            placement="bottomLeft"
            trigger="click"
            content={
              <Stations
                data={data}
                action={action}
                loading={loading}
                setLoading={setLoading}
              />
            }
            arrowPointAtCenter
            overlayClassName={styles.stationsWrapper}
            onVisibleChange={(visible) => setVisible(visible)}
          >
            {Array.isArray(data.stations) && data.stations.length > 0 ? (
              <span className={styles.siteName}>
                <img src="https://panda-water.cn/web4/assets/images/depart.svg" />
                <span>{data.currentStationName}</span>
                <img src="https://panda-water.cn/web4/assets/images/下.svg" style={{transform: !visible ? `rotate(0deg)`:`rotate(180deg)`}}/>
              </span>
            ) : null}
          </Popover>
          {data.weathers && Object.keys(data.weathers).length > 0 ? (
            <span
              className={styles.weatcher}
              style={{
                borderLeft:
                  data.stations.length === 0 ? '0px' : '1px solid #aaaaaa',
              }}
            >
              <img src={data.weathers && data.weathers.icon} />
              <span>{data.weathers && data.weathers.text}</span>
            </span>
          ) : null}
        </div>
      </>
    ),
  };
};
const BasicLayout = props => {
  /* eslint-disable no-unused-vars */
  const {
    children,
    settings,
    location = {
      pathname: '/',
    },
  } = props;
  const basename = getBaseName();
  const history = useHistory();
  const [currentRoutes, setCurrentRoutes] = useState(props.route.routes[props.currentMenuIndex]);
  const [collapse, setCollapse] = useState(false);
  const [loading, setLoading] = useState(true);
  const [cityData, setCityData] = useState({});
  const [pageLoading, setPageLoading] = useState(true);
  const [siteLoading, setSiteLoading] = useState(false);
  const [complexCollapsed, setComplexCollapsed] = useState(false);
  const isMounted = useMountedState();

  const [siteAction, setSiteAction] = useState(() => {
    return new Site(props, setSiteLoading);
  });

  useEffect(() => {
    props.updatePathname(props.location.pathname);
  }, []);

  const extraRender = menuExtraRender(currentRoutes);
  let clearTime = null;

  useEffect(() => {
    setTimeout(() => {
      if (isMounted) setPageLoading(!pageLoading);
    }, 500);
  }, []);

  useEffect(() => {
    const config = findPathByLeafId(
      `${props.location.pathname}` ,
      [currentRoutes],
      '',
      'path',
    );
    config && config.parent && props.updateOpenKeys([config.parent.path]);
    if (config && config.level <= 3) {
      props.updatePathname(config.key);
      props.updateSelectedKeys(config.key);
    } else {

      if(config) {
        const { name, path, parent } = config;
        // setPathname(parent.key);
        props.updatePathname(parent.key);
        props.updateSelectedKeys(parent.path)
        props.updateComplexPathName(path);
        const findDeepLevelConfig = findPathByLeafId(
          parent.path,
          [currentRoutes],
          '',
          'path',
        );
        props.updateComplexConfig(findDeepLevelConfig);
        setCollapse(true);
        history.push(config.path)
      }

    }
  }, [props.location.pathname]);

  useEffect(() => {
    setLoading(true);
    clearTime = setTimeout(() => {
      setCurrentRoutes(props.route.routes[props.currentMenuIndex]);
      setLoading(false);
    }, 100);
    return () => clearTimeout && clearTimeout(clearTime);
  }, [props.currentMenuIndex]);

  useEffect(() => {
    if (_.isEmpty(props.global.token)) {
      history.replace(`/user/login?client=${props.global.client}`);
      return;
    }
    siteAction.getCityStationsForUser().then(res => {
      setCityData(res);
    });
  }, []);

  useMemo(() => {
    window.share.event.on('listenerRemoveTab', () => {
      props.updateSelectedKeys(`/civweb4/?client=${props.global.client}`);
      props.updatePathname(`/civweb4/?client=${props.global.client}`);
      history.push(`/civweb4/?client=${props.global.client}`);
    });
    window.share.event.removeAllListeners('listenerRemoveSigleTab');
  }, [props.pathname]);

  useMemo(() => {
    window.share.event.on('listenerRemoveSigleTab', url => {
      const config = findPathByLeafId(
        `${props.location.pathname}` ,
        [currentRoutes],
        '',
        'path',
      );
      if (config) {
        props.updatePathname(config.key);
        props.updateSelectedKeys(config.key);
      }
    });
    window.share.event.removeAllListeners('listenerRemoveSigleTab');
  }, []);

  // const updateSettings = config => {
  //   props.updageSetting && props.updageSetting(config);
  // };
  const menuDataRef = useRef([]);
  const authorized = useMemo(() => {
      const isHash = window.location.hash !== ""? true: false;
      const path = isHash ?  `${props.location.pathname}${window.location.hash}` : `${props.location.pathname}`
      return getMatchMenu(path || '/', menuDataRef.current).pop() || {
        path: path,
      }
    },
    [location.pathname],
  );
  const handleSelectedKey = (item) => {
    const config = findPathByLeafId(
      item.path,
      [currentRoutes],
      '',
      'path'
    );
    props.updateComplexConfig({});
    props.updateComplexPathName(null);
    if(config && config.routes && config.routes.length > 0 ) {
      props.updateComplexConfig(config)
      props.updateComplexPathName(config.routes[0].path);
      history.push(config.routes[0].path)
    } else {
      history.push(config.path)
    }
    props.updatePathname(item.key);
    props.updateSelectedKeys(`${item.key}`);
    extraRender.onClose();
    // history.push(item.key);
  };

  const handleLogo = event => {
    props.global.userInfo.site ? history.replace(`/industry`) : null;
  };

  const transformPopupMenu = useCallback((key) => {
    if(key.length > 0) {
      const element = document.getElementById(`${key[0]}$Menu`);
      const len = element ? element.children.length: 0;
      if(len >= 6) {
        dom.addClass(element, styles['popup-menu-flex']);
      }
    }
  });

  const others = {
    history: props.history,
    location: props.location,
    match: props.match,
    route: props.menu,
    fixedHeader: true,
    fixSiderbar: true,
    collapsed: collapse
  };
  const headerContentRender = renderTitle(
    props.global.title,
    siteAction,
    cityData,
    siteLoading,
    setSiteLoading,
    collapse,
    others.fixedHeader,
  );

  const menuComplexDataRender = (menuList => {
    return menuList.map(item => {
      const localItem = {
        ...item,
        hideInMenu: false,
        routes: item.routes ? item.routes : undefined,
      };
      return localItem
    });
  });

  const transformComplexSideWidth = () => {
    const complexConfig = props.complexConfig.toJS ? props.complexConfig.toJS(): props.complexConfig;
    let defaultWidth = '150px';
    if(complexCollapsed) {
      return defaultWidth
    }
    if(complexConfig && Object.keys(complexConfig).length > 0 && complexConfig.level === 3) {
      defaultWidth = 150
    } else {
      defaultWidth = 0
    }
    return defaultWidth
  }

  const forceRender = () => {
    if(props.location.pathname === decodeURIComponent(window.location.pathname.split(pkg.name.toLocaleLowerCase())[1])) {
      window.share.event.emit("trigger:route");
    }
  }

  const renderComplexLayout = (children) => {
    const complexConfig = props.complexConfig.toJS ? props.complexConfig.toJS(): props.complexConfig;
    return (
      <ProLayout
          logo={false}
          title={props.global && props.global.title}
          headerRender={false}
          rightContentRender={() => null}
          collapsedButtonRender={false}
          menuHeaderRender={false}
          footerRender={false}
          className={styles.complexLayout}
          location={{
            pathname: props.complexPathName,
          }}
          route={{
            routes: complexConfig && complexConfig.routes && menuComplexDataRender(complexConfig.routes) || []
          }}
          menuItemRender={(menuItemProps, defaultDom) => {
            if (menuItemProps.isUrl || !menuItemProps.path) {
              return defaultDom;
            }
            return <a to={menuItemProps.path}>{defaultDom}</a>;
          }}
          menuProps={{
            onClick: ({ item, key, keyPath, domEvent }) => {
              const config = findPathByLeafId(
                key,
                [complexConfig],
                '',
                'key',
              );
              props.updateComplexPathName(key);
              history.push(config.path)
            },

          }}
          collapsed={complexCollapsed}
          navTheme="light"
          siderWidth={transformComplexSideWidth()}
          style={{
            height: '400px',
          }}>
          {
              complexConfig && (Object.keys(complexConfig).length > 0) ? (
              <span className={styles.complexCollapse} onClick={() => setComplexCollapsed(!complexCollapsed)}>
                <span className={styles.collapsed}>
                  <LeftOutlined />
                </span>
              </span>
            ): null
          }
          {
            children
          }

     </ProLayout>
    )
  }

  const handlerCollapsed = (collapse) => {
    setCollapse(collapse);
    if(!collapse) {
      const config = findPathByLeafId(
        `${props.location.pathname}` ,
        [currentRoutes],
        '',
        'path',
      );
      // fix: 目前菜单限制只支持两级
      if(config && config.parent) {
        const parentConfig = findPathByLeafId(
          config.parent.path,
          [currentRoutes],
          '',
          'path',
        );
        parentConfig && parentConfig.parent && props.updateOpenKeys([parentConfig.parent.path, config.parent.path]);
      }
    }
  }

  const renderSiderMenu = (menuItemProps, defaultDom) => {
    if(collapse) {
      return (
        <>
          {renderIcon(
            menuItemProps.extData && menuItemProps.extData.icon,
            17,
          )}
          <div
            className={`ant-pro-menu-item ${styles.shortName} ${styles.minixName}`}
          >
            {menuItemProps && menuItemProps.extData && menuItemProps.extData.shortName
              ? menuItemProps.extData.shortName
              : menuItemProps.name}
          </div>
          <div
            className={`ant-pro-menu-item ${styles.shortName} ${styles.popverName }`}
          >
            {menuItemProps.name}
          </div>
        </>
      )
    } else {
      return (
        <>
          {renderIcon(
            menuItemProps.extData && menuItemProps.extData.icon,
            17,
          )}
           {defaultDom}
        </>
      )
    }

  }
  const openKeys = props.openKeys;
  return (
    <SecurityLayout loading={true}>
      <ProLayout
        logo={`http://panda-water.cn/web4/${props.global.bannerLogo ? props.global.bannerLogo: 'assets/images/logo/单独图案-白色.svg'}`}
        siderWidth="145px"
        title={props.global && props.global.title}
        onCollapse={collapse => handlerCollapsed(collapse)}
        onMenuHeaderClick={event => handleLogo(event)}
        menuExtraRender={props.menu.length > 0 ? extraRender.render : null}
        rightContentRender={() => <RightContent {...props} />}
        headerContentRender={() => headerContentRender.render}
        menu={{
          loading,
        }}
        location={props.pathname}
        locale={true}
        menuDataRender={() => currentRoutes && currentRoutes.routes}
        menuItemRender={(menuItemProps, defaultDom) => {

          if (menuItemProps.isUrl || !menuItemProps.path) {
              return (
                 <a className={styles.menuItemLink} href={menuItemProps.href} target={menuItemProps.target} title={menuItemProps.name}>
                    {
                      !collapse && (
                          <>
                          {renderIcon(
                            menuItemProps.extData && menuItemProps.extData.icon,
                            17,
                          )}
                          <span className="ant-pro-menu-item">
                            <span className="ant-pro-menu-item-title">{menuItemProps.name}</span>
                          </span>
                        </>
                      )
                    }
                    {
                      collapse && (renderSiderMenu(menuItemProps, defaultDom))
                    }
                </a>
              )
          }
          return (
            <a
              to={menuItemProps.path}
              className={styles.menuItemLink}
              onClick={() => history.push(menuItemProps.path)}
              title={menuItemProps.name}
            >
              {
                renderSiderMenu(menuItemProps, defaultDom)
              }
            </a>
          );
        }}
        subMenuItemRender={(menuItemProps, defaultDom) => {
          return (
            <>
              {renderIcon(
                menuItemProps.extData && menuItemProps.extData.icon,
                17,
              )}
              {collapse ? (
                <div className={`ant-pro-menu-item ${styles.shortName}`}>
                  {menuItemProps.extData && menuItemProps.extData.shortName ? menuItemProps.extData.shortName: menuItemProps.name }
                </div>
              ) : (
                defaultDom
              )}
            </>
          );
        }}
        openKeys={[...openKeys]}
        menuProps={{
          onClick: ({ item, key, keyPath, domEvent }) => {
            domEvent.persist();
            const keyField = key.indexOf("/") > -1 ? 'path': 'key';
            const config = findPathByLeafId(
              key,
              [currentRoutes],
              '',
              keyField
            );
            props.updateComplexConfig({});
            props.updateComplexPathName(null);
            if(config && config.routes && config.routes.length > 0 ) {
              props.updateComplexConfig(config)
              props.updateComplexPathName(config.routes[0].path);
              history.push(config.routes[0].path)
            }
            props.updateSelectedKeys(key);
            props.updatePathname(key);
            forceRender();
          },
          onOpenChange:(openKeys) => {
            props.updateOpenKeys(openKeys.length > 0 ? openKeys: [])
            if(collapse) {
              transformPopupMenu(openKeys);
            }
          },
          selectedKeys: [props.selectedKeys],
          popupClassName: styles.menuPopover,
        }}
        postMenuData={menuData => {
          menuDataRef.current = menuData || [];
          return menuData || [];
        }}
        {...others}
        {...settings}
      >
        {renderRoutes(props.route.routes)}
       
        <Spin
          spinning={pageLoading}
          size="large"
          wrapperClassName={styles.loadding}
        >
        <Panel
          visible={extraRender.toggleSystem}
          keyboard={true}
          onClose={extraRender.onClose}
          data={props.route.routes || []}
          currentMenuIndex={props.currentMenuIndex}
          onChange={index => props.updateCurrentIndex(index)}
          onSelect={item => handleSelectedKey(item)}
        />
         {
          renderComplexLayout( <>
            <Authorized authority={authorized} {...props} noMatch={noMatch}>
              {children}
            </Authorized>
            <div id="micro-container" className="subapp-container" />
          </>)
         }

        </Spin>


        {/*
          <SettingDrawer
            settings={props.settings}
            onSettingChange={config => updateSettings(config)}
            publicPath={`/${basename}/theme`}
          /> */}
      </ProLayout>
    </SecurityLayout>
  );
};
const mapStateToProps = state => {
  return {
    global: state.getIn(['global', 'globalConfig']),
    settings: state.getIn(['global', 'defaultSetting']),
    collapsed: state.getIn(['global', 'collapsed']),
    menu: state.getIn(['global', 'menu']),
    currentMenuIndex: state.getIn(['global', 'currentMenuIndex']),
    flatMenu: state.getIn(['global', 'flatMenu']),
    authValidate: state.getIn(['global', 'authValidate']),
    pathname: state.getIn(['global', 'pathname']),
    selectedKeys: state.getIn(['global', 'selectedKeys']),
    openKeys: state.getIn(['global', 'openKeys']),
    complexConfig: state.getIn(['global', 'complexConfig']),
    complexPathName: state.getIn(['global', 'complexPathName'])
  };
};
const mapDispatchToProps = dispatch => {
  return {
    updageSetting(setting) {
      dispatch(actionCreators.updageSetting(setting));
    },
    updateConfig(config) {
      dispatch(actionCreators.getConfig(config));
    },
    updateCurrentIndex(index) {
      dispatch(actionCreators.updateCurrentIndex(index));
    },
    updateCollapsed(collapsed) {
      dispatch(actionCreators.updateCollapsed(collapsed));
    },
    updateAuthValidate(auth) {
      dispatch(actionCreators.updateAuthValidate(auth));
    },
    updatePathname(pathname) {
      dispatch(actionCreators.updatePathname(pathname));
    },
    updateSelectedKeys(keys) {
      dispatch(actionCreators.updateSelectedKeys(keys));
    },
    updateOpenKeys(keys) {
      dispatch(actionCreators.updateOpenKeys(keys));
    },
    updateComplexConfig(config) {
      dispatch(actionCreators.updateComplexConfig(config))
    },
    updateComplexPathName(pathname) {
      dispatch(actionCreators.updateComplexPathName(pathname))
    }
  };
};
export default connect(
  mapStateToProps,
  mapDispatchToProps,
)(BasicLayout);
