import React, {
  ReactNode,
  useMemo,
  useEffect,
  useCallback,
  /*  useState, */ ReactText,
} from 'react';
import qs from 'qs';
import { env, navRedirectDiscope, redirctToLogin } from '@jy-fe/business';
import { ElementType } from '@jy-fe/business/es/authority';
import { unicodeToChar, useDeepEqualIdentifier } from '@jy-fe/utils';
import classnames from 'classnames';
import locale from 'antd/es/locale/zh_CN';
import ConfigProvider from 'antd/es/config-provider';
import Avatar from 'antd/es/avatar';
import 'antd/es/avatar/style/index';
import Menu from 'antd/es/menu';
import 'antd/es/menu/style/index';
import { /* MenuInfo, */ SelectInfo } from 'rc-menu/es/interface';
import Popover from 'antd/es/popover';
import 'antd/es/popover/style/index';
import message from 'antd/es/message';
import 'antd/es/message/style/index';
import 'antd/es/tooltip/style/index';
import { XuiReactDownloadIcon } from '@jy-fe/icons';
import {
  XuiXladminThemeLayoutInfoDataType,
  XuiXladminThemeLayoutProps,
} from './xui-xladmin-theme-layout.d';
import XuiRoleMenu from '../xui-role-menu';

const XuiThemeLayout: React.FC<XuiXladminThemeLayoutProps> = ({
  systemType,
  admType,
  logoImg,
  logoutImg,
  portraitImg,
  personalSetImg,
  ownModule,
  Link,
  history,
  children,
  initialState,
  onDownload,
  mode,
  onModeChange,
  horizontalSelectedUrl,
  onSelectedHorizontalMenuCallback,
  openedKeys,
  selectedKeys,
  onSelectedSubMenu,
  onSelectedMenuItem,
  positionVisible,
  onPositionVisible,
  roleVisible,
  onRoleVisible,
  roleDataDiscope,
  effectCallback,
}) => {
  const iconfontClassName = useMemo(() => {
    const iconMap = new Map([
      [6, 'recruit-admin'],
      [7, 'xl-admin'],
      [8, 'dd-admin'],
    ]);
    return `iconfont icon-${iconMap.get(admType)}`;
  }, [admType]);
  /** 获取当前路由地址 */
  const { pathname } = location;
  const className = 'xui-ant__xladmin-theme-layout';
  const headerClassName = 'xui-ant__xladmin-theme-layout--header';
  const contentClassName = 'xui-ant__xladmin-theme-layout--content';
  /** 纵向导航栏类名 */
  const verticalPopupMenuClassName = 'xui-ant__xladmin-theme-layout--verticalPopupMenu';
  /** 个人信息浮块类名 */
  const userPopoverClassName = 'xui-ant__xladmin-theme-layout--userPopover';
  /**
   * 以下为权限部分
   */
  /** 解析浏览器?后的参数对 */
  const urlParams = useMemo(() => qs.parse(location.search, { ignoreQueryPrefix: true }), []);

  const { code } = urlParams;

  if (code) {
    delete urlParams.code;
    const searchStr = qs.stringify(urlParams, { addQueryPrefix: true });
    history.replace(`${location.pathname}${searchStr}`);
  }

  const {
    roleData = [],
    redirectPathMap = {},
    verticalNav = [],
    access = [],
    aidMap = {},
    highlightIdMap = {},
  } = initialState || {};

  const accessEqual = useDeepEqualIdentifier(access);
  const aidMapEqual = useDeepEqualIdentifier(aidMap);

  /** 重定向判断 */
  navRedirectDiscope(systemType, redirectPathMap, pathname, redirectPath => {
    history.replace(redirectPath);
  });

  /** 退出登录 */
  const logout = useCallback(() => {
    localStorage.removeItem('token');
    message.success('退出成功');
    location.href = env.ssoLogoutHREF;
  }, []);

  /** 点击横向滚动条后的调用 */
  const selectedHorizontalMenuCallback = useCallback(
    (currentPathname: string, currentRedirectPath: string) => {
      onSelectedHorizontalMenuCallback(currentPathname);
      history.push(currentRedirectPath);
    },
    [history, onSelectedHorizontalMenuCallback],
  );

  /** 获取横向导航栏选中块的相关属性 */
  const selectedHorizontalMenuItem = useCallback(
    (item: any) => {
      if (item.mstyle === '/') {
        selectedHorizontalMenuCallback('/', '/');
      } else {
        navRedirectDiscope(systemType, redirectPathMap, item.mstyle, redirectPath => {
          selectedHorizontalMenuCallback(item.mstyle, redirectPath);
        });
      }
    },
    [systemType, redirectPathMap, selectedHorizontalMenuCallback],
  );

  /** 生成横向导航栏 */
  const HorizontalMenu = useMemo(() => {
    const menus = roleData.map((element: ElementType) => {
      if (element.newTabType === 1) {
        return (
          <a key={element.id || ''} target='__blank' href={element.lowerLevelUrl}>
            <div className={`${headerClassName}--navHead--item`}>{element.mlabel}</div>
          </a>
        );
      }
      if (ownModule.includes(element.mstyle || '')) {
        return (
          <div
            key={element.id || ''}
            className={classnames({
              [`${headerClassName}--navHead--item`]: true,
              [`${headerClassName}--navHead--itemActive`]: horizontalSelectedUrl === element.mstyle,
            })}
            onClick={() => selectedHorizontalMenuItem(element)}
          >
            {element.mlabel}
          </div>
        );
      }
      return (
        <a key={element.id || ''} href={element.lowerLevelUrl}>
          <div className={`${headerClassName}--navHead--item`}>{element.mlabel}</div>
        </a>
      );
    });
    menus.unshift(
      <div
        key='/'
        className={classnames({
          [`${headerClassName}--navHead--item`]: true,
          [`${headerClassName}--navHead--itemActive`]: horizontalSelectedUrl === '/',
        })}
        onClick={() =>
          selectedHorizontalMenuItem({
            mstyle: '/',
          })
        }
      >
        工作台
      </div>,
    );
    return menus;
  }, [ownModule, horizontalSelectedUrl, roleData, selectedHorizontalMenuItem]);

  /** 判断纵向导航栏跳转 */
  const checkVerticalMenu = useCallback(
    (data: any) => {
      if (data.newTabType === 1) {
        return (
          <a rel='noopener noreferrer' target='_blank' href={data.allMenuStyle}>
            {data.mlabel}
          </a>
        );
      }
      if (data.urlType === systemType) {
        return <Link to={data.mstyle}>{data.mlabel}</Link>;
      }
      return <a href={`${data.domainName}${data.mstyle}`}>{data.mlabel}</a>;
    },
    [Link, systemType],
  );

  /** 生成纵向导航栏 */
  const VerticalMenu = useMemo(() => {
    const verticalMenuArray: ReactNode[] = [];
    if (horizontalSelectedUrl !== '/') {
      verticalNav.forEach((element: any) => {
        if (element.pmystyle === horizontalSelectedUrl) {
          if (element.children && element.children.length > 0) {
            verticalMenuArray.push(
              <Menu.SubMenu
                popupClassName={`${verticalPopupMenuClassName}`}
                key={element.id}
                title={
                  <div className={`${verticalPopupMenuClassName}--title`}>
                    <div className={`${verticalPopupMenuClassName}--icon`}>
                      <span className={iconfontClassName}>
                        {unicodeToChar(element.micon || '')}
                      </span>
                    </div>
                    <div>{element.mlabel}</div>
                  </div>
                }
              >
                {element.children.map((child: any) => {
                  return <Menu.Item key={child.id}>{checkVerticalMenu(child)}</Menu.Item>;
                })}
              </Menu.SubMenu>,
            );
          } else {
            verticalMenuArray.push(
              <Menu.Item key={element.id}>
                <div
                  className={`${verticalPopupMenuClassName}--title`}
                  title={mode === 'vertical' ? element.mlabel : ''}
                >
                  <div className={`${verticalPopupMenuClassName}--icon`}>
                    <span className={iconfontClassName}>{unicodeToChar(element.micon || '')}</span>
                  </div>
                  <div>{checkVerticalMenu(element)}</div>
                </div>
              </Menu.Item>,
            );
          }
        }
      });
    }
    return verticalMenuArray;
  }, [horizontalSelectedUrl, mode, verticalNav, iconfontClassName, checkVerticalMenu]);

  /** 用户信息 */
  const info = useMemo<XuiXladminThemeLayoutInfoDataType>(() => {
    let currentInfo = {} as XuiXladminThemeLayoutInfoDataType;
    const infoStr = localStorage.getItem('info');
    if (infoStr) {
      currentInfo = JSON.parse(infoStr);
    }
    return currentInfo;
  }, []);

  /** 用户名 */
  const userName = useMemo<string>(() => {
    if (info.userInfo && info.userInfo.realName) {
      const {
        userInfo: { realName },
      } = info;
      return realName;
    }
    return '';
  }, [info]);

  /** 公司/部门/职位 信息 */
  const positionInfo = useMemo<{ positionIds: string[]; positionNames: string[] }>(() => {
    const { tenancies, rootOrgId, orgId, postId } = info;
    const positionIds = [rootOrgId, orgId, postId];
    const positionNames = [] as string[];
    tenancies?.forEach(tenancy => {
      if (tenancy.tenancyId === rootOrgId) {
        positionNames.push(tenancy.tenancyName);
        tenancy.tenancyDetps?.forEach(dept => {
          if (dept.deptId === orgId) {
            positionNames?.push(dept.deptKey);
            dept.postList?.forEach(post => {
              if (post.postId === postId) {
                positionNames.push(post.postTitle);
              }
            });
          }
        });
      }
    });

    return { positionIds, positionNames };
  }, [info]);

  const changeParams = useMemo(() => {
    const {
      tenancyInfo: { tenancyId },
    } = info;
    return {
      tenancyId,
    };
  }, [info]);

  const onRoleMenuChange = useCallback(
    (params: { postId?: ReactText; roleId: ReactText; orgId?: ReactText }) => {
      redirctToLogin({
        admType,
        redirect_url: location.origin,
        ...params,
        ...changeParams,
      });
    },
    [admType, changeParams],
  );

  const roleMenuData = useMemo(() => {
    const { postRoleResList = [] } = info;
    return postRoleResList;
  }, [info]);

  useEffect(() => {
    const hKey = `/${pathname.split('/')[1]}`;
    /** 锁定横向导航栏高亮 */
    onSelectedHorizontalMenuCallback(hKey);
    // /** 锁定纵向导航栏高亮 */
    let highlightIdMapKey = '';
    for (let i = 0; i < access.length; i++) {
      const accessValue = access[i];
      if (pathname.includes(accessValue)) {
        highlightIdMapKey = accessValue;
        break;
      }
    }
    const highlightIds = highlightIdMap[highlightIdMapKey];
    if (highlightIds) {
      onSelectedSubMenu(highlightIds);
      onSelectedMenuItem([highlightIds[highlightIds.length - 1]]);
    }
  }, [
    pathname,
    accessEqual,
    highlightIdMap,
    onSelectedHorizontalMenuCallback,
    onSelectedSubMenu,
    onSelectedMenuItem,
  ]);

  useEffect(() => {
    roleDataDiscope({
      roleId: info.roleId,
      aidMap,
      userName,
      ...positionInfo,
    });
  }, [userName, roleDataDiscope, info.roleId, aidMapEqual, positionInfo]);

  useEffect(() => {
    effectCallback();
  }, [effectCallback]);

  return (
    <ConfigProvider locale={locale}>
      <div className={className}>
        <div className={`${className}--header`}>
          <div className={`${headerClassName}--logo`}>
            <div className={`${headerClassName}--logo--popover`}>
              <img className={`${headerClassName}--logo--logoImg`} src={logoImg} alt='logo' />
              <XuiRoleMenu
                dataSource={roleMenuData}
                onChange={onRoleMenuChange}
                visible={positionVisible}
                onVisibleChange={onPositionVisible}
                trigger='click'
              >
                <span
                  className={classnames({
                    [iconfontClassName]: true,
                    [`${headerClassName}--logo--arrow`]: true,
                    [`${headerClassName}--logo--arrowClicked`]: positionVisible,
                  })}
                >
                  &#xe6a5;
                </span>
              </XuiRoleMenu>
            </div>
          </div>
          <div className={`${headerClassName}--navHead`}>{HorizontalMenu}</div>
          {onDownload && (
            <div className={`${headerClassName}--download`} onClick={onDownload}>
              <XuiReactDownloadIcon />
            </div>
          )}
          <div className={`${headerClassName}--user`}>
            <Popover
              overlayClassName={`${userPopoverClassName}`}
              placement='bottomRight'
              visible={roleVisible}
              onVisibleChange={onRoleVisible}
              content={
                <div className={`${userPopoverClassName}--content`}>
                  <div className={`${userPopoverClassName}--content--info`}>
                    <Avatar size={40} src={portraitImg} />
                    {userName}
                  </div>
                  <a href={`${env.qlHREF}/person/personsetting`}>
                    <div className={`${userPopoverClassName}--content--row`}>
                      <img src={personalSetImg} alt='个人设置' />
                      个人设置
                      <span className={iconfontClassName}>&#xe6a7;</span>
                    </div>
                  </a>
                  <div
                    onClick={logout}
                    className={classnames(
                      `${userPopoverClassName}--content--row`,
                      `${userPopoverClassName}--content--rowLast`,
                    )}
                  >
                    <img src={logoutImg} alt='退出登录' />
                    退出登录
                  </div>
                </div>
              }
            >
              <div className={`${headerClassName}--user--info`}>
                <Avatar size={24} src={portraitImg} />
                <span className={`${headerClassName}--user--info--name`}>{userName}</span>
                <span
                  className={classnames({
                    [iconfontClassName]: true,
                    [`${headerClassName}--user--info--icon`]: roleVisible,
                  })}
                >
                  &#xe6a5;
                </span>
              </div>
            </Popover>
          </div>
        </div>
        <div className={`${className}--content`}>
          {VerticalMenu.length > 0 && (
            <div
              className={classnames({
                [`${contentClassName}--nav`]: true,
                [`${contentClassName}--navRetracted`]: mode === 'vertical',
              })}
            >
              <Menu
                mode={mode}
                openKeys={openedKeys}
                selectedKeys={selectedKeys}
                onOpenChange={onSelectedSubMenu}
                onSelect={(e: SelectInfo) => onSelectedMenuItem(e.selectedKeys || [])}
                className={`${contentClassName}--nav--verticalMenu`}
              >
                {VerticalMenu}
              </Menu>
              <div className={`${contentClassName}--nav--switch`} onClick={onModeChange}>
                {mode === 'vertical' ? (
                  <div className={iconfontClassName}>&#xe6c6;</div>
                ) : (
                  <div className={iconfontClassName}>&#xe6c8;</div>
                )}
              </div>
            </div>
          )}
          <div id='main' className={`${contentClassName}--main`}>
            {children}
          </div>
        </div>
      </div>
    </ConfigProvider>
  );
};

export default XuiThemeLayout;
