import React, { useState, useEffect, useRef } from "react";
import { RouteContext } from "@ant-design/pro-layout";
import { history, FormattedMessage } from "umi";
import Tags from "./Tags";
import styles from "./index.less";

/**
 * @component TagView 标签页组件
 */
const TagView = ({ children, home }) => {
  const [tagList, setTagList] = useState([]);

  const [currentPath, setCurrentPath] = useState();
  const routeContextRef = useRef();

  useEffect(() => {
    if (routeContextRef.current) {
      handleOnChange(routeContextRef.current);
    }
  }, [routeContextRef.current]);

  // 初始化 visitedViews，设置首页
  const initTags = (routeContext) => {
    const { menuData } = routeContext;
    if (tagList.length === 0 && menuData) {
      const firstTag = menuData.filter((el) => el.path === home)[0];
      if (firstTag) {
        const title = (
          <FormattedMessage
            key={firstTag.name}
            id={`menu.${firstTag.name}`}
            defaultMessage="首页"
          />
        );
        const path = firstTag.path;
        history.push({ pathname: firstTag.path, query: firstTag.query });
        setTagList([
          {
            title,
            path,
            children: firstTag.children,
            refresh: 0,
            active: true,
            key: firstTag.key,
          },
        ]);
      }
    }
  };

  // 监听路由改变
  const handleOnChange = (routeContext) => {
    const { currentMenu } = routeContext;
    // tags初始化
    if (tagList.length === 0) {
      return initTags(routeContext);
    }
    // 判断是否已打开过该页面
    let hasOpen = false;
    if (currentMenu.path) {
      const tagsCopy = tagList.map((item) => {
        if (currentMenu?.path === item.path) {
          hasOpen = true;
          // 刷新浏览器时，重新覆盖当前 path 的 children
          return { ...item, active: true, children };
        } else {
          return { ...item, active: false };
        }
      });

      // 没有该tag时追加一个,并打开这个tag页面
      if (!hasOpen) {
        const title = routeContext.title || "";
        const path = currentMenu?.path;
        tagsCopy.push({
          title,
          path,
          children,
          refresh: 0,
          active: true,
        });
      }
      return setTagList(tagsCopy);
    }
  };

  // 关闭标签
  const handleCloseTag = (tag) => {
    const tagsCopy = tagList.map((el, i) => ({ ...el }));

    // 判断关闭标签是否处于打开状态
    tagList.forEach((el, i) => {
      if (el.path === tag.path && tag.active) {
        const next = tagList[i - 1];
        next.active = true;
        history.push({ pathname: next?.path, query: next?.query });
      }
    });

    setTagList(tagsCopy.filter((el) => el.path !== tag?.path));
  };

  // 关闭所有标签
  const handleCloseAll = () => {
    const tagsCopy = tagList.filter((el) => el.path === home);
    history.push(home);
    setTagList(tagsCopy);
  };

  // 关闭其他标签
  const handleCloseOther = (tag) => {
    const tagsCopy = tagList.filter(
      (el) => el.path === home || el.path === tag.path
    );
    history.push({ pathname: tag?.path, query: tag?.query });
    setTagList(tagsCopy);
  };

  // 刷新选择的标签
  const handleRefreshTag = (tag) => {
    const tagsCopy = tagList.map((item) => {
      if (item.path === tag.path) {
        history.push({ pathname: tag?.path, query: tag?.query });
        return { ...item, refresh: item.refresh + 1, active: true };
      }
      return { ...item, active: false };
    });
    setTagList(tagsCopy);
  };

  return (
    <>
      <RouteContext.Consumer>
        {(value) => {
          setTimeout(() => {
            setCurrentPath(value.currentMenu?.path);
          }, 0);
          routeContextRef.current = value;
          return null;
        }}
      </RouteContext.Consumer>
      <div className={styles.tag_view}>
        <div className={styles.tags_container}>
          <Tags
            tagList={tagList}
            closeTag={handleCloseTag}
            closeAllTag={handleCloseAll}
            closeOtherTag={handleCloseOther}
            refreshTag={handleRefreshTag}
            home={home}
          />
        </div>
      </div>
      <div className={styles.child}>
        <div className={styles.contianbox}>
          {tagList.map((item) => {
            return (
              <div
                key={item.path}
                style={{ display: item.active ? "block" : "none" }}
              >
                <div key={item.refresh}>{item.children}</div>
              </div>
            );
          })}
        </div>
      </div>
    </>
  );
};

export default TagView;
