import * as React from "react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { history } from "umi";
import { observer } from "mobx-react";
import ProLayout, { MenuDataItem, WaterMark } from "@ant-design/pro-layout";
import { IAction } from "@/api/Types";
import { urlToList } from "@/utils/pathTools";
import { AppStore } from "@/store/AppStore";
import { useMenu } from "./useMenu";
import { Session, Storage, Text, Util } from "@/utils";
import { buildIcon, SearchBar } from "@/lib";
import defaultLogo from "@/assets/logo.svg";
import { CaretDownOutlined, CaretRightOutlined, UnorderedListOutlined } from "@ant-design/icons";
import { MenuExpander, MenuFooter } from "@/layouts/BaseLayout/Sider";
import Header from "@/layouts/BaseLayout/Header";
import { getOpenKeysFromSelectedMenu } from "@/layouts/BaseLayout/utils/utils";
import { Breadcrumb, Button, ConfigProvider, Space, Tooltip } from "antd";
import classNames from "classnames";
import { baseLayoutStore as store } from "./Store";
import { Base64 } from "js-base64";
import { HTML_ID_LAYOUT_CONTENT } from "@/constant/ID";
import styles from "./index.less";

const BaseLayout = observer(({ children, location }: any) => {
  const { pathname, query } = location;
  const session: any = Session.get();
  const [collapsed, setCollapse] = useState(false);
  const [selectMenuKey, setSelectMenuKey] = useState([] as Array<string>);
  const [openMenuKey, setOpenMenuKey] = useState([] as Array<string>);
  const [filterMenuData, setFilterMenuData] = useState<any[]>([]);
  const [breadCrumbs, setBreadCrumbs] = useState<any[]>([]);
  const expandMenuRef = useRef<any>();

  const [menuData, breadCrumbMap, defaultCollapseMenus, defaultSelectMenus, originalMenu, filterMenu] = useMenu();
  useEffect(() => {
    ConfigProvider.config({
      theme: {
        primaryColor: store.primaryColor
      }
    });
  }, [store.primaryColor]);

  useEffect(() => {
    setCollapse(false);
  }, [store.layout]);

  useEffect(() => {
    if (_.isEmpty(menuData) || _.isEmpty(breadCrumbMap)) return;
    setOpenMenuKey(store.layout === "side" ? defaultCollapseMenus : []);
    setSelectMenuKey(defaultSelectMenus);
    setFilterMenuData(menuData);
  }, [menuData, breadCrumbMap, defaultCollapseMenus, defaultSelectMenus, store.layout]);

  useEffect(() => {
    if (!collapsed) {
      //菜单数据中父子级关系必须有pid/id
      const openKeys = getOpenKeysFromSelectedMenu(originalMenu, selectMenuKey);
      if (!_.isEmpty(openKeys)) {
        setOpenMenuKey(openKeys);
      }
    }
  }, [collapsed]);

  useEffect(() => {
    if (_.isEmpty(breadCrumbMap)) return;
    const paths = urlToList(pathname);
    let extraBreadcrumbs = _.reduce(paths, (ret: any[], path: string) => {
        const menu = breadCrumbMap[path];
        if (!_.isEmpty(menu)) {
          ret.push({ ...menu });
        }
        return ret;
      },
      []
    );
    const home = breadCrumbMap["/"] || breadCrumbMap["/home"];
    const breadcrumbs = _.isEmpty(home)
      ? extraBreadcrumbs
      : [home].concat(
        _.filter(extraBreadcrumbs, (data: any) => data.key !== home.key)
      );
    setBreadCrumbs(breadcrumbs);
  }, [pathname, breadCrumbMap]);

  const onMenuOpen = useCallback((openKeys: string[]) => {
    setOpenMenuKey(openKeys);
    Storage.session.set("OPEN_MENU_KEY", openKeys);
  }, []);

  const onMenuSelect = useCallback((menu: any) => {
    if (_.isEmpty(menu)) return;
    if (Array.isArray(menu)) {
      setSelectMenuKey(menu);
    } else {
      setSelectMenuKey([menu.key]);
      //@ts-ignore
      setOpenMenuKey((openMenuKey) => [].concat(openMenuKey).concat(menu.keyPath)
      );
    }
  }, []);

  const breadCrumbComp = useMemo(() => {
    return (
      <Breadcrumb>
        {_.map(breadCrumbs, (item: any) => (
          <Breadcrumb.Item
            key={item.path}
            onClick={() => {
              onMenuSelect({
                key: item.id,
                keyPath: [item.id, item.pid]
              });
              history.push(item.path);
            }}
          >
            <a>{buildIcon("", item.icon)} {item.name}</a>
          </Breadcrumb.Item>
        ))}
      </Breadcrumb>
    );
  }, [breadCrumbs]);

  const classes = useMemo(() => {
    return classNames({
      [styles.root]: true,
      [styles[store.navTheme]]: true
    });
  }, [store.navTheme]);

  const onMenuSearch = useCallback((key: any) => {
    if (_.isEmpty(key)) {
      setFilterMenuData(menuData);
    } else {
      setFilterMenuData(filterMenu(originalMenu, key));
    }
  }, [menuData]);

  // 内嵌模式直接渲染子路由
  if (query?.embeded && query?.embeded == "T") {
    return <>{children}</>;
  }

  // const logo = API.SettingService.getSystemParam('logo') || defaultLogo;
  // const appName = API.SettingService.getSystemParam('appName') || '管理系统';
  // const globalWaterMark = API.SettingService.getSystemParam('globalWaterMark') || 'F';
  const logo = defaultLogo;
  const appName = "管理系统";
  const globalWaterMark = "F";

  let layout = (
    <div className={classes}>
      <ProLayout
        className="__layout_main__"
        disableMobile
        fixedHeader
        fixSiderbar
        location={location}
        layout={store.layout}
        splitMenus={store.layout === "mix" && store.splitMenus}
        navTheme={store.layout === "top" ? "dark" : "light"}
        // @ts-ignore
        iconfontUrl={`${Util.getPublicPath()}css/iconfont/iconfont.js`}
        title={Text.toShortText(appName, store.layout === "side" ? 7 : 11)}
        logo={<span onClick={() => history.push("/")}><img src={logo} alt=""/></span>}
        collapsed={collapsed}
        style={{ transition: "all 0.5s ease 0s" }}
        headerContentRender={() =>
          (store.layout === "side" || (store.layout === "mix" && !store.splitMenus)) ? (
            <div className={styles.headContent}>
              {breadCrumbComp}
            </div>
          ) : false
        }
        menuDataRender={(menus: MenuDataItem[]) => filterMenuData || menus}
        menuItemRender={(item) => {
          return (
            <a
              onClick={() => {
                const external = /^https?:\/\//.test(item.path || "");
                Storage.session.set("ACTIVE_MENU_KEY", item.key);
                if (external) {
                  const embedUrl = Base64.encode(item.path || "", true);
                  history.push(`/external?_q=${embedUrl}`);
                } else {
                  history.push(item.path || "/");
                }
              }}
            >
              {typeof item.icon === "string"
                ? buildIcon("FONT", item.icon)
                : item.icon}{" "}
              <label>{item.name}</label>
            </a>
          );
        }}
        menuProps={{
          theme: "light",
          selectedKeys: selectMenuKey,
          openKeys: openMenuKey,
          onOpenChange: onMenuOpen,
          onSelect: onMenuSelect,
          expandIcon: (props) => {
            return props.isOpen ? (
              <CaretDownOutlined style={{ color: "#999" }}/>
            ) : (
              <CaretRightOutlined style={{ color: "#999" }}/>
            );
          }
        }}
        menuExtraRender={() =>
          store.layout === "mix" && store.splitMenus ? null : (
            <div className={styles.expandButton}>
              <Space>
                {collapsed ? null : <SearchBar fillOnSearch onSearch={onMenuSearch} size="small" placeholder="搜索功能"/>}
                <Button size="small" onClick={() => expandMenuRef.current.toggle()}>
                  <Tooltip title="查看全部"><UnorderedListOutlined/></Tooltip>
                </Button>
              </Space>
            </div>
          )}
        rightContentRender={() => (
          <>
            <Header originalMenu={originalMenu} onMenuSelect={onMenuSelect}/>
          </>
        )}
        collapsedButtonRender={() => (
          <MenuFooter
            collapsed={collapsed}
            onCollapse={() => setCollapse((collapsed) => !collapsed)}
          />
        )}
        contentStyle={{ padding: 0, margin: 0, height: "calc(100vh - 48px)" }}
      >
        <div className={styles.content} id={HTML_ID_LAYOUT_CONTENT}>
          <div className={styles.main}>
            {
              //@ts-ignore
              globalWaterMark === "T" ?
              <WaterMark content={`${session?.name}${session?.userNo || ""}`}>{children}</WaterMark> : children
            }
          </div>
        </div>
      </ProLayout>
      <MenuExpander
        //@ts-ignore
        ref={expandMenuRef}
        menuData={menuData}
        selectMenuKey={selectMenuKey}
        onMenuSelect={onMenuSelect}
      />
    </div>
  );

  return layout;
});

export default (props: any) => <BaseLayout {...props} />;

export const resetManageLayoutBreadcrumbs = (
  store: AppStore,
  breadcrumbs: []
) => {
  if (_.isEmpty(store.breadcrumbs)) {
    store.setBreadcrumbs(breadcrumbs);
  }
};

export const resetManageLayoutTopActions = (
  store: AppStore,
  actions: Array<IAction>
) => {
  if (_.isEmpty(store.topActions)) {
    store.setTopActions(actions);
  }
};
