<script>
import { NodeUtils } from "./util.js";
import NodeDrawer from "../NodeDrawer";
const isCondition = data => data.type === "condition" || (data.type === "approver" && (data.isInterflow || data.isBranchFlow));
const notEmptyArray = arr => Array.isArray(arr) && arr.length > 0;
const hasBranch = data => notEmptyArray(data.conditionNodes);
const stopPro = ev => ev.stopPropagation();

function createNormalCard(ctx, conf, h) {
  const classList = ['flow-path-card']
  const afterTrue = (isTrue, name) => (isTrue && classList.push(name), isTrue)
  const isStartNode = afterTrue(NodeUtils.isStartNode(conf), 'start-node')
  const isApprNode = afterTrue(NodeUtils.isApproverNode(conf), 'approver')
  const isCopyNode = afterTrue(NodeUtils.isCopyNode(conf), 'copy')
  const isTimerNode = afterTrue(NodeUtils.isTimerNode(conf), 'timer')
  const isSubFlowNode = afterTrue(NodeUtils.isSubFlowNode(conf), 'subFlow')
  const isMailNode = afterTrue(NodeUtils.isMailNode(conf), 'mail')
  const isServiceTaskNode = afterTrue(NodeUtils.isServiceTaskNode(conf), 'serviceTask')
  const isJumpTaskNode = afterTrue(NodeUtils.isJumpTaskNode(conf), 'jumpTask')
  const isHttpTaskNode = afterTrue(NodeUtils.isHttpTaskNode(conf), 'httpTask')
  const isSQLTaskNode = afterTrue(NodeUtils.isSQLTaskNode(conf), 'sqlTask')
  const isScriptTaskNode = afterTrue(NodeUtils.isScriptTaskNode(conf), 'scriptTask')
  const isShellTaskNode = afterTrue(NodeUtils.isShellTaskNode(conf), 'shellTask')
  const isZhanNode = afterTrue(NodeUtils.isZhanNode(conf), 'zhan')
  const isDingNode = afterTrue(NodeUtils.isDingNode(conf), 'ding')
  const isDxNode = afterTrue(NodeUtils.isDxNode(conf), 'dx')
  const isWxNode = afterTrue(NodeUtils.isWxNode(conf), 'wx')
  return (
    <section class={classList.join(' ')} onClick={this.eventLauncher.bind(ctx, "edit", conf)} >
      <header class="header">
        <div class="title-box" style="height: 100%;width:190px;">
          <span class="title-text">{conf.properties.title}</span>
          {(!isTimerNode) && (
            <input vModel_trim={conf.properties.title} class="title-input" onClick={stopPro} />
          )}
        </div>
        <div class="actions">
          <i class="el-icon-close icon" onClick={this.eventLauncher.bind(ctx, "deleteNode", conf, ctx.data)} ></i>
        </div>
        {(isSubFlowNode) && (
          <el-tag class="async-state" size="mini" effect="plain">{conf.properties.isAsync ? '异步' : '同步'}</el-tag>
        )}
      </header>
      <div class="body">
        <span class="text">{conf.content}</span>
        {
          //  <div class="icon-wrapper right">
          //   <i class="el-icon-arrow-right icon right-arrow"></i>
          // </div>
        }
      </div>
    </section>
  );
}
// arg = ctx, data, h
const createFunc = (...arg) => createNormalCard.call(arg[0], ...arg)
let nodes = {
  start: createFunc,
  addData: createFunc,
  approver: createFunc,
  copy: createFunc,
  timer: createFunc,
  mail: createFunc,
  serviceTask: createFunc,
  jumpTask: createFunc,
  scriptTask: createFunc,
  shellTask: createFunc,
  httpTask: createFunc,
  sqlTask: createFunc,
  ding: createFunc,
  zhan: createFunc,
  wx: createFunc,
  dx: createFunc,
  message: createFunc,
  subFlow: createFunc,
  interflow: createFunc,
  branchFlow: createFunc,
  empty: _ => '',
  condition: function (ctx, conf, h) {
    // <i
    //    class="el-icon-document-copy icon"
    //    onClick={this.eventLauncher.bind(ctx, "copyNode", conf, ctx.data)}
    //  ></i>
    return (
      <section
        class="flow-path-card condition"
        onClick={this.eventLauncher.bind(ctx, "edit", conf)}
      >
        <header class="header">
          <div class="title-box" style="height:20px;width:160px;">
            <span class="title-text">{conf.properties.title}</span>
            <input vModel_trim={conf.properties.title} class="title-input" onClick={stopPro} />
          </div>
          {
            // <span class="priority">优先级{conf.properties.priority + 1}</span>
          }
          <div class="actions">
            <i class="el-icon-close icon" onClick={this.eventLauncher.bind(ctx, "deleteNode", conf, ctx.data)}></i>
          </div>
        </header>
        <div class="body">
          <div class="text">{conf.content}</div>
        </div>
        {
          //  <div
          //   class="icon-wrapper left"
          //   onClick={ctx.eventLauncher.bind(
          //     ctx,
          //     "increasePriority",
          //     conf,
          //     ctx.data
          //   )}
          // >
          // <i class="el-icon-arrow-left icon left-arrow"></i>
          // </div>
          //  <div
          //   class="icon-wrapper right"
          //   onClick={ctx.eventLauncher.bind(
          //     ctx,
          //     "decreasePriority",
          //     conf,
          //     ctx.data
          //   )}
          // >
          //  <i class="el-icon-arrow-right icon right-arrow"></i>
          // </div>
        }
      </section>
    );
  }
};

function addNodeButton(ctx, data, h, isBranch = false) {
  if (data.type === 'condition' && data.properties.conditionType === 1) {
    return (
      <div class="add-node-btn-box flex justify-center">
        <div class="add-node-btn">
          <button class="btn disabled-btn" type="button">
            <i class="icon-ym icon-ym-nav-close icon"></i>
          </button>
        </div>
      </div>
    );
  }
  // 只有非条件节点和条件分支树下面的那个按钮 才能添加新分支树
  let couldAddBranch = !hasBranch(data) || isBranch;
  let canAddAppendBranch = true
  let canAddAppendInterflow = true
  let canAddAppendBranchFlowBranch = true
  let canAddSubFlow = true
  let canAddTimerNode = true
  if (Array.isArray(data.conditionNodes) && data.conditionNodes.length) {
    canAddAppendBranch = false
    canAddAppendInterflow = false
    canAddAppendBranchFlowBranch = false
    canAddSubFlow = false
    canAddTimerNode = false
  }
  if (data.type === 'timer' || (data.childNode && data.childNode.type === 'timer')) {
    canAddTimerNode = false
  }
  if (data.type === 'subFlow') {
    canAddAppendBranch = false
  }
  let isEmpty = data.type === "empty";
  if (isEmpty && !isBranch) {
    return "";
  }
  return (
    <div class="add-node-btn-box flex justify-center">
      <div class="add-node-btn">
        {/* 节点抽屉 内部控制显示/隐藏 */}
        <node-drawer>
          <button class="btn" type="button" slot="operate">
            <i class="el-icon-plus icon"></i>
          </button>
          <div>
            <el-alert title="增加节点后可能会导致下面节点配置的数据传递规则失效" type="warning" closable={false} show-icon />
            <div class="condition-box">
              <el-collapse class="condition-collapse" value="1">
                <el-collapse-item name="1">
                  <span class="condition-title" slot="title">
                    用户或业务人员使用
                  </span>
                  <div class="condition-collapse-list">
                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addApprovalNode", data, isBranch)} >
                        <i class="icon-ym icon-ym-flowTodo"></i>
                      </div>
                      <div>
                        审批节点
                        <el-tooltip placement="top"
                          content='可以作为审批节点或办理节点'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip>

                      </div>
                    </div>
                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addCopyNode", data, isBranch, !canAddTimerNode)} >
                        <i class="icon-ym icon-ym-synForThird"></i>
                      </div>
                      抄送节点
                    </div>
                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addSubFlowNode", data, isBranch, !canAddSubFlow && !isBranch)} >
                        <i class="icon-ym icon-ym-generator-subFlow"></i>
                      </div>
                      <div>子流程
                        <el-tooltip placement="top"
                          content='可以用来对流程图进行解耦'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip></div>
                    </div>


                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addTimerNode", data, isBranch, !canAddTimerNode)} >
                        <i class="icon-ym icon-ym-timer"></i>
                      </div>
                      定时器
                    </div>



                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addJumpTaskNode", data, isBranch)}>
                        <i class="icon-ym icon-ym-flowEntrust-app" style="vertical-align: middle;"></i>
                      </div>
                      <div>
                        路由跳转
                        <el-tooltip placement="top"
                          content='可以用来实现流程图的循环效果!'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip>
                      </div>
                    </div>


                    <div class={{ 'node-item': true, 'condition-disabled': !canAddAppendBranch }}>
                      <div class="condition-icon" onClick={this.eventLauncher.bind(ctx, "appendBranch", data, isBranch, !canAddAppendBranch)}>
                        <i class="ym-custom ym-custom-sitemap"></i>
                      </div>
                      <div>
                        条件分支
                        <el-tooltip placement="top"
                          content='条件分支以及包容分支使用'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip>
                      </div>
                    </div>
                    <div class={{ 'node-item': true, 'condition-disabled': !canAddAppendInterflow }}>
                      <div class="condition-icon" onClick={this.eventLauncher.bind(ctx, "appendInterflowBranch", data, isBranch, !canAddAppendInterflow)}>
                        <i class="icon-ym icon-ym-node"></i>
                      </div>
                      并行分支
                    </div>
                    <div class={{ 'node-item': true, 'condition-disabled': !canAddAppendBranchFlowBranch }}>
                      <div class="condition-icon" onClick={this.eventLauncher.bind(ctx, "appendBranchFlowBranch", data, isBranch, !canAddAppendBranchFlowBranch)}>
                        <i class="icon-ym icon-ym-branch"></i>
                      </div>
                      <div>
                        选择分支
                        <el-tooltip placement="top"
                          content='专门为收发文系统定制,搭配候选人使用效果更佳!!'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip>
                      </div>
                    </div>
                  </div>
                </el-collapse-item>


                <el-collapse-item name="2">
                  <span class="condition-title" slot="title">
                    开发人员使用
                  </span>
                  <div class="condition-collapse-list">
                    <div class="node-item">
                      <div class="condition-icon"
                        onClick={ctx.eventLauncher.bind(ctx, "addServiceTaskNode", data, isBranch)}>
                        <i class="el-icon-s-tools" style="vertical-align: middle;"></i>
                      </div>
                      <div>业务编排
                        <el-tooltip placement="top"
                          content='为Java语言单独扩展,编写Java的业务逻辑'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip>
                      </div>
                    </div>

                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addHttpTaskNode", data, isBranch)}>
                        <i class="el-icon-upload" style="vertical-align: middle;"></i>
                      </div>
                      <div>请求编排
                        <el-tooltip placement="top"
                          content='用来和第三方系统对接'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip>
                      </div>
                    </div>

                    <div class="node-item">
                      <div class="condition-icon"
                        onClick={ctx.eventLauncher.bind(ctx, "addScriptTaskNode", data, isBranch)}>
                        <i class="el-icon-box" style="vertical-align: middle;"></i>
                      </div>
                      脚本编排
                    </div>
                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addShellTaskNode", data, isBranch)}>
                        <i class="el-icon-mobile" style="vertical-align: middle;"></i>
                      </div>
                      运维编排
                    </div>

                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addSQLTaskNode", data, isBranch)}>
                        <i class="icon-ym icon-ym-workFlow" style="vertical-align: middle;"></i>
                      </div>
                      <div>SQL编排
                        <el-tooltip placement="top"
                          content='支持在线编写SQL CRUD语句!'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip>
                      </div>
                    </div>

                    <div class="node-item">
                      <div class="condition-icon">
                        <i class="el-icon-question" style="vertical-align: middle;"></i>
                      </div>
                      <div>外部任务
                        <el-tooltip placement="top"
                          content='让Flowable也具有Camunda的能力,可以为其他编程语言提供桥梁!'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip>
                      </div>
                    </div>



                  </div>

                </el-collapse-item>
                <el-collapse-item name="3">
                  <span class="condition-title" slot="title">
                    通用-消息通知
                  </span>
                  <div class="condition-collapse-list">


                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addMessageNode", data, isBranch)}>
                        <i class="el-icon-question" style="vertical-align: middle;"></i>
                      </div>
                      <div>
                        消息通知
                        <el-tooltip placement="top"
                          content='合并后面几个节点成为1个,暂时可以去在线开发-集成助手中查看相关功能'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip>
                      </div>
                    </div>

                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addMailNode", data, isBranch)}>
                        <i class="el-icon-cpu" style="vertical-align: middle;"></i>
                      </div>
                      发邮件
                    </div>


                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addZhanNode", data, isBranch)}>
                        <i class="el-icon-s-opportunity" style="vertical-align: middle;"></i>
                      </div>
                      发站内信
                    </div>

                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addDingNode", data, isBranch)}>
                        <i class="el-icon-share" style="vertical-align: middle;"></i>
                      </div>
                      发送钉钉
                    </div>

                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addDxNode", data, isBranch)}>
                        <i class="el-icon-mobile-phone" style="vertical-align: middle;"></i>
                      </div>
                      发送短信
                    </div>

                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addWxNode", data, isBranch)}>
                        <i class="el-icon-copy-document" style="vertical-align: middle;"></i>
                      </div>
                      发送微信
                    </div>
                  </div>




                </el-collapse-item>
                <el-collapse-item name="4">
                  <span class="condition-title" slot="title">
                    Erp编排
                  </span>

                  <div class="condition-collapse-list">
                    <el-alert title="可以暂时先去在线开发-集成助手中查看相关功能" type="warning" closable={false} show-icon />
                    <div class="node-item">
                      <div class="condition-icon" onClick={ctx.eventLauncher.bind(ctx, "addAddDataNode", data, isBranch)}>
                        <i class="el-icon-question" style="vertical-align: middle;"></i>
                      </div>
                      <div>
                        新增数据
                        <el-tooltip placement="top"
                          content='暂时可以去在线开发-集成助手中查看相关功能'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip>
                      </div>
                    </div>


                    <div class="node-item">
                      <div class="condition-icon">
                        <i class="el-icon-question" style="vertical-align: middle;"></i>
                      </div>
                      <div>
                        修改数据
                        <el-tooltip placement="top"
                          content='暂时可以去在线开发-集成助手中查看相关功能'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip>
                      </div>
                    </div>

                    <div class="node-item">
                      <div class="condition-icon">
                        <i class="el-icon-question" style="vertical-align: middle;"></i>
                      </div>
                      <div>
                        删除数据
                        <el-tooltip placement="top"
                          content='暂时可以去在线开发-集成助手中查看相关功能'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip>
                      </div>
                    </div>


                    <div class="node-item">
                      <div class="condition-icon">
                        <i class="el-icon-question" style="vertical-align: middle;"></i>
                      </div>
                      <div>
                        获取单\多条数据
                        <el-tooltip placement="top"
                          content='暂时可以去在线开发-集成助手中查看相关功能'>
                          <a class="el-icon-question tooltip-question"></a>
                        </el-tooltip>
                      </div>
                    </div>

                  </div>


                </el-collapse-item>
              </el-collapse>
            </div>
          </div>
        </node-drawer>
      </div>
    </div>
  );
}

function NodeFactory(ctx, data, h) {
  if (!data) return
  const showErrorTip = ctx.verifyMode && NodeUtils.checkNode(data) === false
  let content = "未设置审批人"
  if (NodeUtils.isStartNode(data)) content = `未设置${this.flowType == 1 ? "功能" : "表单"}配置`
  if (NodeUtils.isConditionNode(data)) content = "未设置条件"
  if (NodeUtils.isSubFlowNode(data)) content = "未设置发起人"
  let res = [],
    branchNode = "",
    selfNode = (
      <div class="node-wrap">
        <div class={`node-wrap-box ${data.type} ${NodeUtils.isInterflowNode(data) ? 'interflow' : ''} ${NodeUtils.isBranchFlowNode(data) ? 'branchFlow' : ''} ${showErrorTip ? 'error' : ''}`}>
          <el-tooltip content={content} placement="top" effect="dark">
            <div class="error-tip" onClick={this.eventLauncher.bind(ctx, "edit", data)}>!!!</div>
          </el-tooltip>
          {nodes[data.type].call(ctx, ctx, data, h)}
          {addNodeButton.call(ctx, ctx, data, h)}
        </div>
      </div>
    );

  if (hasBranch(data)) {
    // 如果节点是数组 一定为条件分支 添加分支样式包裹
    // {data.childNode && NodeFactory.call(ctx, ctx, data.childNode, h)}
    if (NodeUtils.isConditionNode(data.conditionNodes[0])) {
      branchNode = (
        <div class="branch-wrap">
          <div class="branch-box-wrap">
            <div class="branch-box flex justify-center relative">
              <el-popover placement="right" trigger="click" width="180" class='popover'>
                <div class="add-popover-main add-condition-popover-main">
                  <div class="condition-box">
                    <div onClick={this.eventLauncher.bind(null, 'appendConditionNode', data, 0)}>
                      <div class="condition-icon">
                        <i class="icon-ym icon-ym icon-ym-condition"></i>
                      </div>
                      条件逻辑
                    </div>
                    <div onClick={this.eventLauncher.bind(null, 'appendConditionNode', data, 1)}>
                      <div class="condition-icon">
                        <i class="icon-ym icon-ym icon-ym-turn"></i>
                      </div>
                      转向逻辑
                    </div>
                  </div>
                </div>
                <button class="btn" type="button" slot="reference">
                  添加条件
                </button>
              </el-popover>
              {data.conditionNodes.map(d => NodeFactory.call(ctx, ctx, d, h))}
            </div>
          </div>
          {addNodeButton.call(ctx, ctx, data, h, true)}
        </div >
      );
    }
    if (NodeUtils.isInterflowNode(data.conditionNodes[0])) {
      branchNode = (
        <div class="branch-wrap">
          <div class="branch-box-wrap">
            <div class="branch-box flex justify-center relative">
              <button onClick={this.eventLauncher.bind(ctx, "appendInterflowNode", data)}
                class="btn">
                添加分流
              </button>
              {data.conditionNodes.map(d => NodeFactory.call(ctx, ctx, d, h))}
            </div>
          </div>
          {addNodeButton.call(ctx, ctx, data, h, true)}
        </div>
      );
    }
    if (NodeUtils.isBranchFlowNode(data.conditionNodes[0])) {
      branchNode = (
        <div class="branch-wrap">
          <div class="branch-box-wrap">
            <div class="branch-box flex justify-center relative">
              <button onClick={this.eventLauncher.bind(ctx, "appendBranchFlowNode", data)}
                class="btn">
                添加分支
              </button>
              {data.conditionNodes.map(d => NodeFactory.call(ctx, ctx, d, h))}
            </div>
          </div>
          {addNodeButton.call(ctx, ctx, data, h, true)}
        </div>
      );
    }
  }

  if (isCondition(data)) {
    return (
      <div class="col-box">
        <div class="center-line"></div>
        <div class="top-cover-line"></div>
        <div class="bottom-cover-line"></div>
        {selfNode}
        {branchNode}
        {NodeFactory.call(ctx, ctx, data.childNode, h)}
      </div>
    );
  }
  res.push(selfNode);
  branchNode && res.push(branchNode);
  data.childNode && res.push(NodeFactory.call(ctx, ctx, data.childNode, h));
  return res;
}

function addEndNode(h) {
  return <section class="end-node">流程结束</section>;
}

export default {
  components: {
    NodeDrawer
  },
  props: {
    data: { type: Object, required: true },
    // 点击发布时需要校验节点数据完整性 此时打开校验模式
    verifyMode: { type: Boolean, default: true },
  },
  watch: {

  },
  methods: {
    /**
     *事件触发器 统筹本组件所有事件并转发到父组件中
     * @param { Object } 包含event（事件名）和args（事件参数）两个参数
     */
    eventLauncher(event, ...args) {
      stopPro(args[args.length - 1])
      let list = ['appendBranch', 'appendBranchFlowBranch', 'appendInterflowBranch', 'addTimerNode']
      if (list.includes(event) && args[args.length - 2]) return
      // args.slice(0,-1) vue 会注入MouseEvent到最后一个参数 去除事件对象
      let param = { event, args: args.slice(0, -1) };
      if (event === 'deleteNode') {
        this.$confirm('此操作将永久删除该节点，删除后可能会导致下面节点配置的数据传递规则失效，是否继续?', '提示', {
          type: 'warning'
        }).then(() => {
          this.$emit("emits", param);
        }).catch(() => { });
      } else {
        this.$emit("emits", param);
      }
    }
  },
  render(h) {
    return (
      <div style="display: inline-flex; flex-direction: column; align-items: center;">
        {this.data && NodeFactory.call(this, this, this.data, h)}
        {addEndNode(h)}
      </div>
    );
  }
};
</script>

<style lang="scss" scoped>
@import 'index.scss';
</style>
