/*
 * Author: 黎永顺
 * name: 薪资项目-拓扑图
 * Description:
 * Date: 2023/10/19
 */
import React, { FunctionComponent, useEffect, useMemo, useState } from "react";
import { DecompositionTreeGraph, NodeConfig } from "@ant-design/graphs";
import { notification } from "antd";
import { exceptStr } from "@/utils/common";
import API from "@/api";
// @ts-ignore
import uuidV4 from "uuid/v4";

interface OwnProps {
}

type Props = OwnProps;
const index: FunctionComponent<Props> = (props) => {
  const [dataSource, setDataSource] = useState<any>({});
  const [i18n, setI18n] = useState<any>({});
  useEffect(() => {
    window.parent.postMessage({ type: "initDiagram" }, "*");
    window.addEventListener("message", receiveMessageFromIndex, false);
    return () => {
      window.removeEventListener("message", receiveMessageFromIndex, false);
    };
  }, []);
  const receiveMessageFromIndex = (event: any) => {
    const data: any = exceptStr(event.data);
    if (!_.isEmpty(data)) {
      const { i18n, acctEmpId, salaryItemId, salarySobId } = data;
      setI18n(i18n);
      init({ acctEmpId, salaryItemId, salarySobId });
    }
  };
  const init = (paylaod: any) => {
    API.CalculateService.getSalarysobItemTopology(paylaod).then(({ data }) => {
      const { status, data: result } = data;
      if (status) {
        const dataSource = {
          id: result.salaryItemId.toString(),
          value: { title: result.salaryItemName, formula: result.formula, items: [{ text: result.result }] },
          children: !_.isEmpty(result.children) ? traverse(result.children) : []
        };
        setDataSource(dataSource);
      }
    });
  };
  const getChildren = async (nodeCfg: NodeConfig) => {
    return findChildren(extractTree(dataSource.children), nodeCfg.id);
  };
  const openNotification = (data: any) => {
    const { value: { formula } } = data;
    notification.destroy();
    if (_.isEmpty(formula)) return;
    const { formula: description } = formula;
    notification.open({
      message: i18n["公式"],
      duration: 5,
      description,
      style: { maxWidth: 600 }
    });
  };
  const component: any = useMemo(() => {
    const config = {
      data: {
        ...dataSource,
        children: dataSource.children ? _.map(dataSource.children, o => ({ ...o, children: null })) : null
      },
      autoFit: false, animate: true,
      nodeCfg: {
        getChildren,
        autoWidth: true,
        title: {
          style: { fill: "#333" },
          containerStyle: () => {
            return {
              fill: "#f7fbfe",
              stroke: "#e5e5e5"
            };
          }
        },
        nodeStateStyles: {
          hover: {
            stroke: '#e5e5e5',
            lineWidth: 1,
          },
        },
        items: {
          style: (cfg: any, group: any, type: string) => {
            const styles = {
              value: { fill: "#333" }
            };
            return styles[type];
          }
        },
        style: {
          stroke: "#e5e5e5"
        }
      },
      markerCfg: (cfg: any) => {
        const { g_level, id } = cfg;
        return {
          show: (g_level === 0 && !_.isEmpty(dataSource.children)) || getStorageIds(dataSource.children).includes(id)
        };
      },
      onReady: (graph: any) => {
        graph.on("node:click", (evt: any) => {
          if (_.isEmpty(evt.target.attrs) || JSON.stringify(evt.target.attrs).indexOf("cursor") !== -1) return;
          openNotification(evt.item._cfg.model);
        });
        setTimeout(() => {
          graph.zoom(1);
        });
      },
      behaviors: ["drag-canvas", "zoom-canvas"]
    };
    // @ts-ignore
    return !_.isEmpty(dataSource) ? <DecompositionTreeGraph {...config} /> : null;
  }, [dataSource]);
  return component;
};

export default index;

const traverse: any = (arr: any[]) => {
  return _.map(arr, item => {
    if (!_.isEmpty(item.children)) {
      const uuid = uuidV4();
      return {
        id: uuid,
        value: { title: item.salaryItemName, formula: item.formula, items: [{ text: item.result }] },
        children: traverse(item.children)
      };
    } else {
      const uuid = uuidV4();
      return {
        id: uuid, value: { title: item.salaryItemName, formula: item.formula, items: [{ text: item.result }] }
      };
    }
  });
};
const findChildren: any = (arr: any[], id: string) => {
  const dataSource = _.find(arr, o => o.id === id).children;
  return _.map(dataSource, o => ({ ...o, children: [] }));
};
/*
 * Author: 黎永顺
 * Description:数组扁平换
 * Params:
 * Date: 2023/10/26
 */
export const extractTree = (data: any[]) => {
  if (!data.length) return [];
  const list: any[] = [];
  const getObj = (arr: any[]) => {
    arr.forEach((row: any) => {
      let obj = {};
      obj = JSON.parse(JSON.stringify(row));
      list.push(obj);
      if (row.children) {
        getObj(row.children);
      }
    });
    return list;
  };
  return getObj(data);
};
/*
 * Author: 黎永顺
 * Description: 有children子集的id集合
 * Params:
 * Date: 2023/10/26
 */
const getStorageIds = (array: any[]) => {
  let ids: any = [];
  const getIds = (array: any, ids: any) => {
    array.forEach((item: any) => {
      if (item.children) ids.push(item.id);
      if (item.children) ids = getIds(item.children, ids);
    });
    return ids;
  };
  if (Array.isArray(array)) {
    if (array.length === 0) return [];
  } else {
    return [];
  }
  ids = getIds(array, ids);
  return ids;
};
