import React from 'react';
import { message, Alert, Icon, Menu } from 'antd';
import { Search } from '@woowalker/feui'
import ComponentBase from "../ComponentBase";
import styles from '../Component.css';
import _ from 'lodash';
import { addRuleAndGroups, extendRule, getDataFieldValue, guid, initFilter, permissionUtils } from "../../utils/common";

class TreeBaseComponent extends ComponentBase {
  constructor(props) {
    super(props);
    this.state = {
      data: {},
      treeConfig: {},
      treeLoadParam: {},
      treeSelectedNodeId: {},
      treeExpandedKeys: {}
    };
    this.defaultTreeCode = 'tree';
  };
  componentDidMount() {
    super.componentDidMount();
    this.onLoadData();
    const { onRegLoadFunc, } = this.props;
    if (typeof onRegLoadFunc === 'function') {
      onRegLoadFunc(({ treeCode = this.defaultTreeCode, searchValue }) => {
        this.onLoadTreeData({
          treeCode,
          searchValue,
        });
      });
    }
  }

  componentWillReceiveProps(NextProps) {
    super.componentWillReceiveProps(NextProps);
  }

  onLoadData() {
    const treeConfigs = this.onLoadTreeConfigList();
    if (treeConfigs && treeConfigs.length) {
      let treeConfig = this.state.treeConfig;
      if (!treeConfig) {
        treeConfig = {};
      }
      treeConfigs.forEach(t => {
        if (t.treeCode === undefined) {
          t.treeCode = this.defaultTreeCode;
        }
        treeConfig[t.treeCode] = t;
      });
      this.setState({
        treeConfig,
      }, () => {
        const tempTreeConfig = this.state.treeConfig;
        if (tempTreeConfig) {
          Object.keys(tempTreeConfig).forEach((n) => {
            this.onLoadTreeData({
              treeCode: n,
              treeConfig: tempTreeConfig[n],
            });
          });
        }
      });
    }
  }

  onLoadTreeConfigList() { }

  onLoadTreeData({ treeCode, searchValue, onComplete }) {
    const treeConfig = this.getTreeConfig({ treeCode });
    if (treeConfig) {
      const { sort, order, relationField, relationId, api, orgType, ignoreOrgRule } = treeConfig;

      if (!api) return;
      const treeLoadParam = this.state.treeLoadParam;
      let loadParam = treeLoadParam[treeCode];

      if (!loadParam) {
        loadParam = initFilter(this.props.login.OrgId, '', sort, order);
        treeLoadParam[treeCode] = loadParam;
      }
      const rules = this.props && this.props.data && this.props.data.rules ? this.props.data.rules : [];
      const json = JSON.parse(JSON.stringify(loadParam));//{ ...loadParam };
      if (
        (!relationField || relationField !== "PARENT_ID") &&
        _.findIndex(rules, (o) => { return o.field === 'PARENT_ID' }) < 0) {
        extendRule(json, "PARENT_ID", 1, "");
      }

      if (rules) {
        rules.forEach(item => {
          extendRule(json, item.field, item.operator, item.value, item.isSysParam);
        });
      }
      if (orgType) {
        json.OrgType = orgType;
      }
      if (searchValue) {
        addRuleAndGroups(json, searchValue);
      }

      //填加关联字段过滤
      if (relationField && relationId) {
        extendRule(json, relationField, 1, relationId);
      }

      // 是否忽略组织权限
      if (ignoreOrgRule) {
        json.IgnoreOrgRule = ignoreOrgRule
      }

      this.props.dispatch({
        type: 'app/getTableData',
        payload: json,
        url: api,
        onComplete: (ret) => {
          if (ret) {
            if (!ret.IsSuccessful) {
              message.error(ret.ErrorMessage);
            }
            this.setTreeData({
              treeCode,
              data: ret.Data,
              onComplete,
            }, () => {
              this.onAfterLoadTreeData();
            });
          }
        }
      });
    }
  }

  onAfterLoadTreeData() { }

  onLoadTreeChildData({ treeCode, treeNode }) {
    return new Promise((resolve, reject) => {
      if (treeNode.props.dataRef.IS_LEAF) {
        reject();
      } else {
        const treeConfig = this.getTreeConfig({ treeCode });
        if (treeConfig) {
          const { sort, order, api } = treeConfig;
          let json = initFilter(this.props.login.OrgId, '', sort, order);
          extendRule(json, "PARENT_ID", 1, treeNode.props.dataRef.ID);
          this.props.dispatch({
            type: 'app/getTableData',
            payload: json,
            url: api,
            onComplete: (ret) => {
              if (ret) {
                if (!ret.IsSuccessful) {
                  message.error(ret.ErrorMessage);
                }
                const treeData = this.getTreeData({ treeCode });
                this.getTreeDataById(treeData, treeNode.props.dataRef.ID, (data) => {
                  if (!data.Children) {
                    data.Children = [];
                  }
                  if (ret.Data) {
                    ret.Data.forEach(t => {
                      data.Children.push(t);
                    });
                  }
                });
                this.setTreeData({
                  treeCode,
                  data: treeData,
                });
              }
            }
          });
        }
        resolve();
      }
    });
  }

  /*
  获取树配置
   */
  getTreeConfig(params) {
    const { treeCode = this.defaultTreeCode } = params ? params : {};
    let treeConfig = this.state.treeConfig;
    if (!treeConfig) {
      treeConfig = {};
    }
    return treeConfig[treeCode];
  }

  /*
  设置树配置
   */
  setTreeConfig(params) {
    const { treeConfig, onComplete } = params ? params : {};
    let tempTreeConfig = this.state.treeConfig;
    if (!tempTreeConfig) {
      tempTreeConfig = {};
    }
    if (treeConfig.treeCode === undefined) {
      treeConfig.treeCode = this.defaultTreeCode;
    }
    tempTreeConfig = {
      ...tempTreeConfig,
      [treeConfig.treeCode]: treeConfig,
    };
    this.setState({
      treeConfig: tempTreeConfig
    }, () => {
      if (typeof onComplete === 'function') {
        onComplete();
      }
    })
  }

  /*
  获取树数据
   */
  getTreeData(params) {
    const { treeCode = this.defaultTreeCode } = params ? params : {};
    let data = this.state.treeData;
    if (!data) {
      data = {};
    }
    return data[treeCode];
  }

  /*
  设置树数据
   */
  setTreeData({ treeCode, data, onComplete }) {
    let tempData = this.state.treeData;
    if (!tempData) {
      tempData = {};
    }
    if (treeCode === undefined) {
      treeCode = this.defaultTreeCode;
    }
    tempData = {
      ...tempData,
      [treeCode]: data,
    };
    this.setState({
      treeData: tempData,
    }, () => {
      if (typeof onComplete === 'function') {
        onComplete();
      }
    });
  }

  /*
  获取选中节点ID
   */
  getSelectedNodeId(params) {
    const { treeCode = this.defaultTreeCode } = params ? params : {};
    let treeSelectedNodeId = this.state.treeSelectedNodeId;
    if (!treeSelectedNodeId) {
      treeSelectedNodeId = {};
    }
    return treeSelectedNodeId[treeCode];
  }

  /*
  设置选中节点ID
   */
  setSelectedNodeId({ treeCode, id, onComplete }) {
    let treeSelectedNodeId = this.state.treeSelectedNodeId;
    if (!treeSelectedNodeId) {
      treeSelectedNodeId = {};
    }
    if (treeCode === undefined) {
      treeCode = this.defaultTreeCode;
    }
    treeSelectedNodeId = {
      ...treeSelectedNodeId,
      [treeCode]: id
    };
    this.setState({
      treeSelectedNodeId
    }, () => {
      if (typeof onComplete === 'function') {
        onComplete();
      }
    });
  }

  /*
  获取树节点标题
   */
  getTreeNodeTitle({ treeCode, titleColumns, data }) {
    if (data.isAdd) {
      return '新增节点';
    }
    if (!titleColumns) {
      const treeConfig = this.getTreeConfig({ treeCode });
      if (treeConfig) {
        titleColumns = treeConfig.titleColumns;
      }
    }
    if (titleColumns && titleColumns.length) {
      let title = '';
      titleColumns.forEach(t => {
        let tmpValue = getDataFieldValue(data, t.field);
        tmpValue = tmpValue == null || tmpValue == undefined ? '' : tmpValue;
        title += tmpValue + "/";
      });
      title = title.substring(0, title.length - 1);
      return title;
    }
  }

  /*
 树拖拽
 {treeCode:树编号,dragId：当前拖拽的节点ID,dragParentId：拖拽后节点父节点ID,
   originDragParentId：原始节点父节点ID,dropId：拖拽到节点ID（一般不用）}
 */
  onTreeDrop({ treeCode, dragId, dragParentId, originDragParentId, dropId }) {

  }
  /*
  获取选中节点标题
   */
  getTreeNodeSelectedTitle(params) {
    const { treeCode = this.defaultTreeCode } = params ? params : {};
    let data = null;
    const selectId = this.getSelectedNodeId({ treeCode });
    const treeConfig = this.getTreeConfig({ treeCode });
    if (selectId) {
      const treeData = this.getTreeData({ treeCode });
      this.getTreeDataById(
        treeData,
        selectId,
        (nodeData) => {
          data = nodeData;
        }
      );
    }
    if (data) {
      if (data.isAdd) {
        return '新增节点';
      }
      if (treeConfig && treeConfig.titleColumns && treeConfig.titleColumns.length) {
        return this.getTreeNodeTitle({ treeCode, titleColumns: treeConfig.titleColumns, data });
      }
      return data.NAME;
    }
  }
  /*
  选中树节点
   */
  selectTreeNode = (params) => {
    const { treeCode = this.defaultTreeCode, id } = params ? params : {};
    if (id) {
      const treeData = this.getTreeData({ treeCode });
      this.getTreeDataById(treeData, id, (ret) => {
        this.setSelectedNodeId({
          treeCode,
          id,
          onComplete: () => {
            this.onSelectedTreeNode({
              ...params,
              treeCode,
              data: ret,
            });
          }
        });
      });
    }
    else {
      this.setSelectedNodeId({
        treeCode,
        id,
        onComplete: () => {
          this.onSelectedTreeNode({
            ...params,
            treeCode,
            data: null,
          });
        }
      });
    }
  };

  /*
  选中树节点事件
   */
  onSelectedTreeNode(params) {
    const { treeCode, id, data } = params ? params : {};

  }

  /*
  设置展开树键值
   */
  setTreeExpandedKeys({ treeCode, expandedKeys, onComplete }) {
    if (treeCode === undefined) {
      treeCode = this.defaultTreeCode;
    }
    let treeExpandedKeys = this.state.treeExpandedKeys;
    if (!treeExpandedKeys) {
      treeExpandedKeys = {};
    }
    treeExpandedKeys = {
      ...treeExpandedKeys,
      [treeCode]: expandedKeys,
    };
    this.setState({
      treeExpandedKeys
    }, () => {
      if (typeof onComplete === 'function') {
        onComplete();
      }
    });
  }

  /*
  获取右键菜单
   */
  getTreeNodeContextMenu(params) {
    const { data, treeCode = this.defaultTreeCode } = params ? params : {};
    const treeConfig = this.getTreeConfig({ treeCode });
    const selectId = this.getSelectedNodeId({ treeCode });
    if (treeConfig) {
      //添加同级菜单按钮到列表中
      if (treeConfig.btns) {
        const index = treeConfig.btns.findIndex(t => t.btnType === 3);
        const index2 = treeConfig.btns.findIndex(t => t.btnType === 3 && t.isAddChild);
        if (index !== -1 && index2 === -1) {
          const item = treeConfig.btns[index];
          treeConfig.btns.splice(index, 0, { ...item, id: guid(), pId: item.id, isAddChild: true });
        }
      }
      return <Menu className={styles.contextMenuList}>
        {
          treeConfig.btns ? treeConfig.btns.map(t => {
            if (t.btnType === undefined) return null;
            if (t.isRule && !permissionUtils(this.props.login).checkBtn(treeConfig.formId, (t.pId ? t.pId : t.id))) return null;
            if (!this.showBtn(t, data)) return null;
            if (t.btnType === 3) {//新增
              if (t.isAddChild) {
                return <Menu.Item key="sibling" onClick={() => this.addTreeNode({ treeCode, level: 'parent', id: data.ID })} disabled={data.isAdd || t.disabled || selectId !== data.ID}>
                  <Icon type="plus" />新增同级
                </Menu.Item>
              }
              return <Menu.Item key="next" onClick={() => this.addTreeNode({ treeCode, level: 'childred', id: data.ID })} disabled={data.isAdd || t.disabled || selectId !== data.ID}>
                <Icon type="plus" />新增下级
                </Menu.Item>
            }
            else if (t.btnType === 4) {//删除
              return <Menu.Item key="del" onClick={() => this.deleteTreeNode({ treeCode, id: data.ID })} disabled={t.disabled || selectId !== data.ID}>
                <Icon type="delete" />删除
              </Menu.Item>
            }
            else if (t.btnType === 10) {//复制新增
              return <Menu.Item key={'copy'} onClick={() => this.addTreeNode({ treeCode, level: 'parent', id: data.ID, isCopy: true })}
                disabled={data.isAdd || !selectId || t.disabled || selectId !== data.ID}>
                <Icon type="copy" />复制新增
              </Menu.Item>
            }
            return null;
          }) : null
        }
        {
          this.onTreeNodeContextMenu({ ...params, treeConfig })
        }
      </Menu>;
    }
  }

  showBtn = (t, nodeData) => {
    let isshow = false;
    if (!t.btn_condition) {
      isshow = true;
    } else {
      isshow = false;
      const conditions = t.btn_condition.split('|');
      for (let condition of conditions) {
        const fields = condition.split(',');
        const val = getDataFieldValue(nodeData, fields[0]);
        if (parseInt(fields[1], 10) === 1 && String(val) === String(fields[2])) {
          isshow = true;
          break;
        }
      }
    }

    return isshow
  }

  /*
    获取树节点右击菜单
    {
    data, //节点数据
    treeCode,//树编号
    treeConfig//树配置信息
    }
   */
  onTreeNodeContextMenu(params) {
    const { data, treeCode, treeConfig } = params ? params : {};
  }


  /*
  新增树节点
   */
  addTreeNode({ treeCode, isCopy, level, id }) {
    let treeData = this.getTreeData({ treeCode });
    if(!treeData){
      treeData=[];
    }
    const newId = guid();
    const menuKey = 'treeNodeMenuKey_' + treeCode + '_' + id;//右击菜单键值  用于菜单隐藏
    const data = { ID: newId, IS_LEAF: true, isAdd: true };
    let treeExpandedKeys = this.state.treeExpandedKeys;//展开键值列表
    if (!treeExpandedKeys) {
      treeExpandedKeys = {};
    }
    let parentId = null;
    if (level === 'parent') {//新增当前节点同级
      this.getTreeParentById(treeData, id, (parent) => {
        if (parent) {
          parentId = parent.ID;
        }
      });
    }
    else if (level === 'childred') {//新增当前节点下级
      parentId = id;
    }

    // 删除前一次增加未保存项
    function delAdding(loop) {
      if (loop) {
        loop.forEach((item, key) => {
          if (item.hasOwnProperty("isAdd") && item["isAdd"]) {
            loop.splice(key, 1);
          }
          if (item.Children) {
            delAdding(item.Children)
          }
        })
      }
    }

    delAdding(treeData);

    //添加到树数据中
    this.addTreeDataByParentId(treeData, parentId, data);

    if (parentId) {
      let tempKeys = treeExpandedKeys[treeCode];
      if (!tempKeys) {
        tempKeys = [];
      }
      tempKeys.push(parentId);
      treeExpandedKeys = {
        ...treeExpandedKeys,
        [treeCode]: tempKeys,
      };
    }
    let numArr = treeData
    let num = 0;
    if (parentId) {
      // 找跟自己同级的节点，并分配NUM
      const findChildren = function (arr, targetId) {
        const find = arr.find(ar => ar.ID === targetId)
        if (find && find.Children && find.Children.length) {
          numArr = find.Children
        } else {
          for (let i = 0, j = arr.length; i < j; i++) {
            if (arr[i].Children && arr[i].Children.length) {
              findChildren(arr[i].Children, targetId)
            }
          }
        }
      }
      findChildren(treeData, parentId)
    }
    if (numArr) {
      numArr.forEach((n, i) => {
        if (n.NUM && n.NUM > num) {
          num = n.NUM;
        }
      });
    }

    num++;
    data.NUM = num;
    data.PARENT_ID = parentId;
    let copySrcId = '';
    if (isCopy) {
      copySrcId = id;
    }
    this.setState({
      treeExpandedKeys,
      [menuKey]: false,
      copySrcId,
    }, () => {
      this.setTreeData({
        treeCode, data: treeData, onComplete: () => {
          this.selectTreeNode({ treeCode, isAdd: true, id: newId });
        }
      });
      this.onAfterAddTreeNode({ treeCode, newId, parentId, id, isCopy, newData: data, });
    });
  }

  /*
    新增树节点 后
    treeCode,
    newId, //新增节点ID
    parentId,//新增节点的父节点ID
    id,//来源节点ID  可能为空
    isCopy,//是否拷贝
    newData,//新增节点数据
   */
  onAfterAddTreeNode(params) {
    const { treeCode, newId, parentId, id, isCopy, newData } = params;
  }


  /*
  删除树节点
   */
  deleteTreeNode(params) {
    const { treeCode = this.defaultTreeCode, id } = params ? params : {};
    const menuKey = 'treeNodeMenuKey_' + treeCode + '_' + id;//右击菜单键值  用于菜单隐藏
    this.setState({
      [menuKey]: false,
    });
    const treeConfig = this.getTreeConfig({ treeCode });
    if (treeConfig) {
      const { deleteApi } = treeConfig;
      const doDeleteTreeNode = () => {
        const treeData = this.getTreeData({ treeCode });
        let nodeData = null;
        this.deleteTreeDataById(treeData, id, null, (d) => {
          nodeData = d;
        });
        if (deleteApi) {
          this.addDeleteLog({ formCode: treeConfig.formCode, ids: id, formId: treeConfig.formId, extData: ('删除数据，详情：' + (nodeData ? JSON.stringify(nodeData) : '')) });
        }
        this.setState({
          parentId: '',
        }, () => {
          this.selectTreeNode({ treeCode, id: null });
          this.onAfterDeleteTreeNode({ treeCode, id });

        });
      };
      if (deleteApi) {
        this.props.dispatch({
          type: 'app/deleteItemBatch',
          payload: {
            ids: id
          },
          url: deleteApi,
          onComplete: (ret) => {
            if (ret) {
              message.success('删除成功');
              doDeleteTreeNode();
            }
          }
        })
      }
      else {
        doDeleteTreeNode();
      }
    }
  }

  /*
  删除树节点 后
  {
  treeCode,树编号
  id//删除节点ID
  }

   */
  onAfterDeleteTreeNode(params) {
    const { treeCode, id } = params ? params : {};
  }




  /*
  根据树编号渲染树
   */
  getRenderTreeByConfig(treeCode) {
    if (treeCode === undefined) {
      treeCode = this.defaultTreeCode;
    }
    const treeConfig = this.getTreeConfig({ treeCode });
    if (treeConfig) {
      const treeData = this.getTreeData({ treeCode });
      const hasData = treeData && treeData.length;
      const { formCode, queryCode, sort, order, titleColumns, draggable } = treeConfig;
      const title = this.getTreeNodeSelectedTitle({ treeCode });
      const expandedKeys = this.state.treeExpandedKeys[treeCode];
      const selectedId = this.getSelectedNodeId({ treeCode });
      return <div className={styles.treeBox}>
        <Search formCode={formCode} code={queryCode} onSearch={(value) => this.onLoadTreeData({ treeCode, searchValue: value })} />
        {
          hasData
            ? <div className={styles.tipToContextMenu}>右键[添加/修改]</div>
            : <div className={`${styles.tipToContextMenu} ${styles.addNode}`} onClick={() => this.addTreeNode({ treeCode, level: 'all', id: null })}><Icon type="plus" />新增</div>
        }
        {
          title
          && <Alert message={<span>当前选中：{title}</span>} type="success" />
        }
        {
          hasData
            ? this.getRenderTree({
              data: treeData,  //数据
              treeCode,//树编号
              onLoadData: (({ treeCode: tempTreeCode, treeNode }) => {//加载数据事件
                return this.onLoadTreeChildData({
                  treeCode: tempTreeCode,
                  treeNode
                });
              }),
              onSelect: (params => {//选中节点事件
                this.selectTreeNode(params);
              }),
              expandedKeys,//已展开直接列表
              selectedId,//当前选中节点ID
              onExpand: ({ expandedKeys }) => {//展开事件
                this.setTreeExpandedKeys({ treeCode, expandedKeys });
              },
              sort,//排序字段
              order,//排序类型
              onContextMenu: (params) => {//获取节点右击菜单列表事件
                return this.getTreeNodeContextMenu({ ...params, treeCode });
              },
              getTreeNodeTitle: ({ data }) => {//获取节点标题函数
                return this.getTreeNodeTitle({ treeCode, titleColumns, data });
              },
              draggable,//是否拖拽
              onDrop: (updateData, dragId, dragParentId, dropId, originDragParentId) => {//拖拽事件
                this.setTreeData({
                  treeCode, data: updateData, onComplete: () => {
                    this.onTreeDrop({ treeCode, dragId, dragParentId, dropId, originDragParentId });
                  }
                });
              },
            }) : <div style={{ textAlign: "center" }}>无数据</div>
        }
      </div>
    }
  }



  render() {
    return (
      <div>
      </div>
    )
  }
}

export default TreeBaseComponent;
