/*
 * @Author: yuananting
 * @Date: 2021-02-23 18:28:50
 * @LastEditors: yuananting
 * @LastEditTime: 2021-03-23 14:16:07
 * @Description: 助学工具-题库-主页面分类管理
 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
 */
import React, { Component } from "react";
import Breadcrumbs from "@/components/Breadcrumbs";
import "./QuestionCategoryManage.less";
import NewEditQuestionBankCategory from "./modal/NewEditQuestionBankCategory";
import QuestionBankService from "@/domains/question-bank-domain/QuestionBankService";
import User from "@/common/js/user";
import {
  Tree,
  Input,
  Space,
  Button,
  Menu,
  Dropdown,
  message,
  Modal,
} from "antd";
import ShowTips from "@/components/ShowTips";
const { DirectoryTree } = Tree;
const { Search } = Input;
const { confirm } = Modal;
class QuestionCategoryManage extends Component {
  constructor(props) {
    super(props);
    this.state = {
      NewEditQuestionBankCategory: null, //新增或编辑分类模态框
      treeData: [],
      treeMap: {},
      selectedKeys: ["0"],
      autoExpandParent: true,
    };
  }

  componentDidMount() {
    this.queryCategoryTree("search");
  }

  // 查询分类树
  queryCategoryTree = (operateType, categoryName) => {
    this.setState({ categoryName });
    let query = {
      source: 0,
      categoryName,
      userId: User.getStoreUserId(),
      tenantId: User.getStoreId(),
    };
    QuestionBankService.queryCategoryTree(query).then((res) => {
      const { result = [] } = res;
      let str = "未分类";
      if (categoryName) {
        this.setState({ autoExpandParent: true });
        if (str.indexOf(categoryName) < 0) {
          this.setState({
            treeData: this.renderTreeNodes(result, categoryName),
          });
          let nodeId = [];
          Object.keys(this.state.treeMap).forEach((item) => {
            nodeId.push(item);
          });
          this.setState({ expandedKeys: nodeId });
        } else {
          const defaultNode = {
            id: "0",
            categoryName: "未分类",
            categoryCount: 0,
            parentId: "0",
            categoryLevel: 0,
          };
          result.unshift(defaultNode);
          this.setState({
            treeData: this.renderTreeNodes(result, categoryName),
          });
          let nodeId = [];
          Object.keys(this.state.treeMap).forEach((item) => {
            nodeId.push(item);
          });
          if (operateType === "search") {
            this.setState({ expandedKeys: nodeId });
          }
        }
      } else {
        this.setState({ autoExpandParent: false });
        const defaultNode = {
          id: "0",
          categoryName: "未分类",
          categoryCount: 0,
          parentId: "0",
          categoryLevel: 0,
        };
        result.unshift(defaultNode);
        this.setState({
          treeData: this.renderTreeNodes(result, categoryName),
        });
        if (operateType === "search") {
          this.setState({ expandedKeys: [] });
        }
      }
    });
  };

  // 删除分类
  delCategory = (item) => {
    return confirm({
      title: "确认删除该分类吗？",
      content: "删除后，分类下的所有内容将自动转入“未分类”中。",
      icon: (
        <span className="icon iconfont default-confirm-icon">&#xe839; </span>
      ),
      okText: "删除",
      okType: "danger",
      cancelText: "取消",
      onOk: () => {
        let params = {
          categoryId: item.id,
          source: 0,
          tenantId: User.getStoreId(),
          userId: User.getStoreUserId(),
        };
        QuestionBankService.delCategory(params).then((res) => {
          if (res.success) {
            message.success("删除分类成功");
            this.queryCategoryTree("change");
          }
        });
      },
    });
  };

  // 新增或编辑分类
  newEditQuestionCategory = (categoryType, addLevelType, type, node) => {
    let title = "";
    let label = "";
    switch (categoryType) {
      case "newEqualLevelCategory":
        title = "新增分类";
        label = "分类名称";
        break;
      case "newChildLevelCategory":
        title = "新增子分类";
        label = "子分类名称";
        break;
      case "editEqualLevelCategory":
        title = "编辑分类";
        label = "分类名称";
        break;
      case "editChildLevelCategory":
        title = "编辑子分类";
        label = "子分类名称";
        break;
    }
    const m = (
      <NewEditQuestionBankCategory
        node={node}
        addLevelType={addLevelType}
        type={type}
        treeData={this.state.treeData}
        title={title}
        label={label}
        close={() => {
          this.queryCategoryTree("change");
          this.setState({
            NewEditQuestionBankCategory: null,
          });
        }}
      />
    );
    this.setState({ NewEditQuestionBankCategory: m });
  };

  initDropMenu = (item) => {
    return (
      <Menu>
        <Menu.Item key="0">
          <span
            onClick={() => {
              let categoryType =
                item.categoryLevel === 0
                  ? "editEqualLevelCategory"
                  : "editChildLevelCategory";
              this.newEditQuestionCategory(categoryType, "equal", "edit", item);
            }}
          >
            重命名
          </span>
        </Menu.Item>
        <Menu.Item key="1">
          <span
            onClick={() => {
              this.delCategory(item);
            }}
          >
            删除
          </span>
        </Menu.Item>
      </Menu>
    );
  };

  getRelatedNodes = (parentId) => {
    return this.state.treeMap[parentId]
      ? this.state.treeMap[parentId].sonCategoryList
      : [];
  };

  getParentDragNodesLevel = (dragNode) => {
    if (!dragNode) {
      return [];
    }
    let dragNodes = [];
    dragNodes.push(dragNode.id);

    if (dragNode.parentId != 0) {
      dragNodes = dragNodes.concat(
        this.getParentDragNodesLevel(this.state.treeMap[dragNode.parentId])
      );
    }
    return dragNodes;
  };

  getDragNodesLevel = (dragNode) => {
    let dragNodes = [];
    if (dragNode.sonCategoryList && dragNode.sonCategoryList.length > 0) {
      dragNode.sonCategoryList.forEach((item) => {
        dragNodes.push(item.categoryLevel);
        if (item.sonCategoryList && item.sonCategoryList.length > 0) {
          dragNodes = dragNodes.concat(this.getDragNodesLevel(item));
        }
      });
    }
    return [...new Set(dragNodes)];
  };

  onDrop = (info) => {
    if (this.state.categoryName) {
      return;
    }
    // 未分类不可以拖拽
    if (
      info.dragNode.categoryName === "未分类" &&
      info.dragNode.categoryLevel === 0
    )
      return message.info("未分类”为默认分类暂不支持移动");

    // 不允许其他节点拖拽到未分类之前
    if (
      info.node.categoryName === "未分类" &&
      info.dropToGap &&
      info.dropPosition === -1
    )
      return;

    let targetParentId = info.dropToGap ? info.node.parentId : info.node.id;
    if (this.state.treeMap[targetParentId].categoryLevel === 4) {
      return message.info("最多支持5级分类");
    } else {
      let nodesArr = this.getDragNodesLevel(
        this.state.treeMap[info.dragNode.id]
      );
      let parentArr = this.getParentDragNodesLevel(
        this.state.treeMap[targetParentId]
      );
      if (nodesArr.length + parentArr.length > 4) {
        return message.info("最多支持5级分类");
      }
    }

    let relatedNodes = this.getRelatedNodes(targetParentId);
    if (relatedNodes && relatedNodes.length === 30) {
      return message.info("最多只能添加30个子分类");
    }
    const dropKey = info.node.key;
    const dragKey = info.dragNode.key;
    const dropPos = info.node.pos.split("-");
    const dropPosition =
      info.dropPosition - Number(dropPos[dropPos.length - 1]);

    const loop = (data, key, callback) => {
      for (let i = 0; i < data.length; i++) {
        if (data[i].key === key) {
          return callback(data[i], i, data);
        }
        if (data[i].sonCategoryList) {
          loop(data[i].sonCategoryList, key, callback);
        }
      }
    };
    const data = [...this.state.treeData];

    let getSuf = function (name, originCategoryName, sufIndex) {
      if (relatedNodes && relatedNodes.length > 0) {
        let sameNameNodes = [];
        relatedNodes.forEach((item) => {
          if (item.id === info.dragNode.id) return true;
          if (item.categoryName === name) {
            sameNameNodes.push(item);
          }
        });
        if (sameNameNodes.length > 0) {
          sufIndex++;
          return getSuf(
            originCategoryName + `(${sufIndex})`,
            originCategoryName,
            sufIndex
          );
        }
      }
      return sufIndex;
    };

    let dragObj;
    loop(data, dragKey, (item, index, arr) => {
      arr.splice(index, 1);
      item.parentId = targetParentId;
      if (item.originCategoryName) {
        item.categoryName = item.originCategoryName;
      } else {
        item.originCategoryName = item.categoryName;
      }
      info.dragNode.categoryName = item.originCategoryName;
      let sufIndex = getSuf(
        info.dragNode.categoryName,
        item.originCategoryName,
        0
      );
      item.categoryName = item.categoryName + (sufIndex ? `(${sufIndex})` : "");
      item.categoryName =
        item.originCategoryName + (sufIndex ? `(${sufIndex})` : "");
      dragObj = item;
    });

    if (!info.dropToGap) {
      loop(data, dropKey, (item) => {
        item.sonCategoryList = item.sonCategoryList || [];
        item.sonCategoryList.unshift(dragObj);
      });
    } else if (
      (info.node.props.sonCategoryList || []).length > 0 &&
      info.node.props.expanded &&
      dropPosition === 1
    ) {
      loop(data, dropKey, (item) => {
        item.sonCategoryList = item.children || [];
        item.sonCategoryList.unshift(dragObj);
      });
    } else {
      let ar;
      let i;
      loop(data, dropKey, (item, index, arr) => {
        ar = arr;
        i = index;
      });
      if (dropPosition === -1) {
        ar.splice(i, 0, dragObj);
      } else {
        ar.splice(i + 1, 0, dragObj);
      }
    }
    data.shift();
    let newTreeData = this.renderTreeNodes(this.handleLoop(data, 0));
    this.setState({ treeData: newTreeData });
    let params = {
      categoryList: newTreeData,
      source: 0,
      tenantId: User.getStoreId(),
      userId: User.getStoreUserId(),
    };
    QuestionBankService.editCategoryTree(params).then((res) => {
      this.queryCategoryTree("change");
    });
  };

  handleLoop = (data, level) => {
    data.map((item, index) => {
      item.sort = index;
      item.categoryLevel = level;
      if (item.sonCategoryList) {
        item.children = this.handleLoop(item.sonCategoryList, level + 1);
        item.sonCategoryList = this.handleLoop(item.sonCategoryList, level + 1);
      }
      return item;
    });
    return data;
  };

  /** 获取树状第一级key 设置默认展开第一项 */
  getFirstLevelKeys = (data) => {
    let firstLevelKeys = [];
    data.forEach((item) => {
      if (item.categoryLevel === 0) {
        firstLevelKeys.push(item.key);
      }
    });
    return firstLevelKeys;
  };

  /** 树状展开事件 */
  onExpand = (expandedKeys) => {
    this.setState({ expandedKeys });
  };

  renderTreeNodes = (data, value) => {
    let newTreeData = data.map((item) => {
      item.title = item.categoryName;
      item.key = item.id;
      item.title = (
        <div
          style={{
            opacity:
              !value || (value && item.categoryName.indexOf(value) > -1)
                ? 1
                : 0.5,
          }}
          className="node-title-div"
          onMouseOver={(e) => {
            let mouseNodeOpts = e.currentTarget.getElementsByTagName("div")[0];
            if (mouseNodeOpts) {
              mouseNodeOpts.style.visibility = "visible";
            }
          }}
          onMouseOut={(e) => {
            let mouseNodeOpts = e.currentTarget.getElementsByTagName("div")[0];
            if (mouseNodeOpts) {
              mouseNodeOpts.style.visibility = "hidden";
            }
          }}
        >
          <span>{item.categoryName}</span>
          {item.categoryName !== "未分类" && (
            <Space className="title-opts" size={50}>
              <span
                className="icon iconfont"
                onClick={() => {
                  let nodesCount = 0;
                  const { treeData } = this.state;
                  if (item.categoryLevel === 0) {
                    // 第一层级
                    nodesCount = treeData.length;
                  } else {
                    let parentNodes = this.getRelatedNodes(item.parentId);
                    if (
                      parentNodes.length > 0 &&
                      parentNodes[0].sonCategoryList
                    ) {
                      nodesCount = parentNodes[0].sonCategoryList.length;
                    } else {
                      nodesCount = 0;
                    }
                  }
                  if (nodesCount >= 30) {
                    message.info("最多只能添加30个分类");
                    return;
                  }
                  this.newEditQuestionCategory(
                    "newEqualLevelCategory",
                    "equal",
                    "new",
                    item
                  );
                }}
              >
                &#xe7f5; 同级
              </span>
              {item.categoryLevel < 4 && (
                <span
                  className="icon iconfont"
                  onClick={() => {
                    if (
                      item.sonCategoryList &&
                      item.sonCategoryList.length >= 30
                    ) {
                      message.info("最多只能添加30个子分类");
                      return;
                    }
                    this.newEditQuestionCategory(
                      "newChildLevelCategory",
                      "child",
                      "new",
                      item
                    );
                  }}
                >
                  &#xe7f8; 子级
                </span>
              )}
              <Dropdown overlay={this.initDropMenu(item)}>
                <span className="icon iconfont">更多 &#xe7f7;</span>
              </Dropdown>
            </Space>
          )}
        </div>
      );
      item.icon =
        item.id === "default" ? (
          <span className="icon iconfont" style={{ color: "#FBD140" }}>
            &#xe7f6;
          </span>
        ) : (
          <span className="icon iconfont" style={{ color: "#FBD140" }}>
            &#xe7f1;
          </span>
        );

      if (item.sonCategoryList) {
        item.children = this.renderTreeNodes(item.sonCategoryList, value);
      }
      return item;
    });

    let map = {};

    let topItem = [];
    data.forEach((item) => {
      topItem.push(item);
    });

    this.setState({
      treeMap: Object.assign(this.getTreeMap(data, map), {
        0: {
          sonCategoryList: topItem,
        },
      }),
    });
    return newTreeData;
  };

  getTreeMap = (data, map) => {
    data.forEach((item) => {
      map[item.id] = item;
      if (item.sonCategoryList && item.sonCategoryList.length > 0) {
        this.getTreeMap(item.sonCategoryList, map);
      }
    });

    return map;
  };

  /** 树状选中事件 */
  onSelect = (selectedKeys) => {
    this.setState({ selectedKeys });
  };

  render() {
    const {
      treeData,
      expandedKeys,
      selectedKeys,
      autoExpandParent,
    } = this.state;
    return (
      <div className="page question-category-manage">
        {getParameterByName("from") === "aid" ? (
          <Breadcrumbs
            navList="课程分类"
            goBack={() =>
              window.RCHistory.push({
                pathname: "/question-bank-index",
              })
            }
          />
        ) : (
          <div className="content-header">课程分类</div>
        )}
        <div className="box">
          <div className="search-condition">
            <span className="search-label">搜索名称：</span>
            <Search
              placeholder="请输入名称"
              style={{ width: "calc(100% - 84px)" }}
              onSearch={(value) => this.queryCategoryTree("search", value)}
            />
          </div>
          <Button
            type="primary"
            onClick={() => {
              if (treeData.length >= 30) {
                message.info("最多只能添加30个分类");
                return;
              }
              this.newEditQuestionCategory(
                "newEqualLevelCategory",
                "equal",
                "new"
              );
            }}
          >
            新增一级分类
          </Button>
          <div className="show-tips" style={{ marginTop: 12 }}>
            <ShowTips message="为方便管理，该分类用于课程、培训计划、题库、知识库等模块，改动将同步各模块更新" />
          </div>
          <div className="course-category-tree">
            <DirectoryTree
              expandedKeys={expandedKeys}
              autoExpandParent={autoExpandParent}
              onExpand={this.onExpand}
              selectedKeys={selectedKeys}
              onSelect={this.onSelect}
              draggable
              blockNode
              onDrop={this.onDrop}
              treeData={treeData}
            ></DirectoryTree>
          </div>
        </div>
        {this.state.NewEditQuestionBankCategory}
      </div>
    );
  }
}

export default QuestionCategoryManage;
