<template>
  <div>
    <el-dialog
      class="modify-flow-detail page-dialog"
      :visible.sync="modalIsShow"
      title="流程图编辑"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="false"
      append-to-body
      fullscreen
      destroy-on-close
      @open="visibleChange"
    >
      <div class="box-justify" slot="title">
        <h4 class="el-dialog__title">流程图编辑：{{ instance.name }}</h4>
        <div>
          <el-button @click="cancel">取消</el-button>
          <el-button type="primary" :disabled="isSubmit" @click="submit"
            >发布</el-button
          >
        </div>
      </div>

      <div class="part-box part-box-pad" style="padding-bottom: 5px">
        <el-form
          ref="modalFormComp"
          :model="flowInfo"
          :rules="rules"
          label-width="140px"
        >
          <el-form-item prop="modelType" label="指定审批人类型：">
            <el-select
              v-model="flowInfo.modelType"
              placeholder="请选择流程指定审批人类型"
              @change="initFlowNodes"
            >
              <el-option
                v-for="(val, key) in FLOW_MODEL_TYPE"
                :key="key"
                :value="key"
                :label="val"
              ></el-option>
            </el-select>
          </el-form-item>
        </el-form>
      </div>

      <div class="flow-box">
        <div class="flow-content">
          <div class="flow-main">
            <!-- nodes -->
            <div
              v-for="node in nodes"
              :key="node.id"
              :id="`node-${node.id}`"
              :class="[
                'flow-node',
                `node-${node.type.toLowerCase()}`,
                { 'is-active': curNode.id === node.id }
              ]"
              @click="toSelectNode(node)"
            >
              <div v-if="node.type === 'PROCESS'" class="flow-node-title">
                <i
                  v-if="node.type === 'PROCESS'"
                  :class="nodeIcons['PROCESS']"
                ></i
                >审批人
              </div>
              <div v-if="node.type === 'PROCESS'" class="flow-node-content">
                <template v-if="!IS_APPROVE_SET">
                  <div v-if="node.property.approveUserType === 'USER'">
                    <p>
                      {{
                        node.property.approveUsers
                          .map(item => item.name)
                          .join("，")
                      }}
                    </p>
                    <p v-if="node.property.copyForUsers.length">
                      抄送：{{
                        node.property.copyForUsers
                          .map(item => item.name)
                          .join("，")
                      }}
                    </p>
                  </div>
                  <div v-else>
                    <p>
                      {{
                        node.property.approveRoles
                          .map(item => item.name)
                          .join("，")
                      }}
                    </p>
                  </div>
                </template>
                <template
                  v-if="IS_APPROVE_SET && node.property.approveUserCountType"
                >
                  <p>
                    方式：{{
                      APPROVE_USER_COUNT_TYPE[
                        node.property.approveUserCountType
                      ]
                    }}
                  </p>
                  <p>
                    范围：{{
                      APPROVE_USER_SELECT_RANGE[
                        node.property.approveUserSelectRange
                      ]
                    }}
                  </p>
                  <p v-if="node.property.approveUserSelectRange === 'ROLE'">
                    角色：{{
                      node.property.approveUserSelectRoles
                        .map(item => item.name)
                        .join("，")
                    }}
                  </p>
                </template>
              </div>
              <div v-else class="flow-node-content">
                <span><i :class="nodeIcons[node.type]"></i></span>
                <span>{{ node.content }}</span>
              </div>
              <div v-if="node.type !== 'END'" class="flow-link">
                <div class="node-add" @click.stop="toAddNode(node.id)">
                  <i class="el-icon-plus"></i>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="flow-property">
          <div v-if="curNode.id" class="flow-property-main" :key="curNode.id">
            <h3 class="flow-property-title">节点属性</h3>
            <!-- 管理员指定审批人 -->
            <div v-if="!IS_APPROVE_SET" class="property-part">
              <h4 class="property-part-title">设置审批人</h4>
              <div class="flow-radio">
                <el-radio-group
                  v-model="curNode.property.approveUserType"
                  size="small"
                  @change="curNodeChange"
                >
                  <el-radio
                    v-for="(val, key) in APPROVE_USER_TYPE"
                    :key="key"
                    :label="key"
                    >{{ val }}</el-radio
                  >
                </el-radio-group>
              </div>
              <!-- 添加成员 -->
              <div
                v-if="curNode.property.approveUserType === 'USER'"
                class="flow-users"
              >
                <el-button
                  size="small"
                  type="primary"
                  @click="toAddUser('approveUsers')"
                  >添加成员</el-button
                >
                <span class="tips-info">（最多添加5个）</span>
                <div class="user-list">
                  <el-tag
                    v-for="user in curNode.property.approveUsers"
                    :key="user.id"
                    size="small"
                    closable
                    :disable-transitions="false"
                    @close="deleteApproveUser('approveUsers', user)"
                  >
                    {{ user.name }}
                  </el-tag>
                  <el-button
                    class="user-clear"
                    type="danger"
                    size="mini"
                    plain
                    @click="clearApproveUsers('approveUsers')"
                    >清空</el-button
                  >
                </div>
              </div>
              <!-- 添加角色 -->
              <div v-else class="flow-users">
                <el-button
                  size="small"
                  type="primary"
                  @click="toAddApproveRole('approveRoles')"
                  >添加角色</el-button
                >
                <div class="user-list">
                  <el-tag
                    v-for="role in curNode.property.approveRoles"
                    :key="role.id"
                    size="small"
                    closable
                    :disable-transitions="false"
                    @close="deleteApproveRole('approveRoles', role)"
                  >
                    {{ role.name }}
                  </el-tag>
                  <el-button
                    class="user-clear"
                    type="danger"
                    size="mini"
                    plain
                    @click="clearApproveRole('approveRoles')"
                    >清空</el-button
                  >
                </div>
              </div>
            </div>
            <!-- 发起人指定审批人 -->
            <div v-else class="property-part">
              <h4 class="property-part-title">设置审批人</h4>
              <el-form label-width="80px">
                <el-form-item label="选择方式：">
                  <el-select
                    v-model="curNode.property.approveUserCountType"
                    class="width-full"
                    placeholder="请选择方式"
                    @change="curNodeChange"
                  >
                    <el-option
                      v-for="(val, key) in APPROVE_USER_COUNT_TYPE"
                      :key="key"
                      :value="key"
                      :label="val"
                    ></el-option>
                  </el-select>
                </el-form-item>
                <el-form-item label="选择范围：">
                  <el-select
                    v-model="curNode.property.approveUserSelectRange"
                    class="width-full"
                    placeholder="请选择范围"
                    @change="curNodeChange"
                  >
                    <el-option
                      v-for="(val, key) in APPROVE_USER_SELECT_RANGE"
                      :key="key"
                      :value="key"
                      :label="val"
                    ></el-option>
                  </el-select>
                </el-form-item>
                <el-form-item
                  v-if="curNode.property.approveUserSelectRange === 'ROLE'"
                  label="指定角色："
                >
                  <el-button
                    size="small"
                    type="primary"
                    @click="toAddApproveRole('approveUserSelectRoles')"
                    >添加角色</el-button
                  >
                  <div class="user-list">
                    <el-tag
                      v-for="role in curNode.property.approveUserSelectRoles"
                      :key="role.id"
                      size="small"
                      closable
                      :disable-transitions="false"
                      @close="deleteApproveRole('approveUserSelectRoles', role)"
                    >
                      {{ role.name }}
                    </el-tag>
                    <el-button
                      class="user-clear"
                      type="danger"
                      size="mini"
                      plain
                      @click="clearApproveRole('approveUserSelectRoles')"
                      >清空</el-button
                    >
                  </div>
                </el-form-item>
              </el-form>
            </div>
            <!-- 抄送人 -->
            <div class="property-part">
              <h4 class="property-part-title">设置抄送人</h4>
              <div class="flow-users">
                <el-button
                  size="small"
                  type="primary"
                  @click="toAddUser('copyForUsers')"
                  >添加成员</el-button
                >
                <span class="tips-info">（最多添加5个）</span>
                <div class="user-list">
                  <el-tag
                    v-for="user in curNode.property.copyForUsers"
                    :key="user.id"
                    closable
                    size="small"
                    :disable-transitions="false"
                    @close="deleteApproveUser('copyForUsers', user)"
                  >
                    {{ user.name }}
                  </el-tag>
                  <el-button
                    class="user-clear"
                    type="danger"
                    size="mini"
                    plain
                    @click="clearApproveUsers('copyForUsers')"
                    >清空</el-button
                  >
                </div>
              </div>
            </div>
            <!-- 高级设置 -->
            <div class="property-part">
              <h4 class="property-part-title">高级设置</h4>
              <p class="property-desc">多人审批时采用的审批方式</p>
              <div class="flow-radio-v">
                <el-radio-group
                  v-model="curNode.property.multipleUserApproveType"
                  size="small"
                  @change="curNodeChange"
                >
                  <el-radio
                    v-for="(val, key) in MULTIPLE_USER_APPROVE_TYPE"
                    :key="key"
                    :label="key"
                    >{{ val }}</el-radio
                  >
                </el-radio-group>
              </div>
            </div>
            <!-- 驳回设置 -->
            <div class="property-part">
              <h4 class="property-part-title">驳回设置</h4>
              <p class="property-desc">允许驳回节点</p>
              <div class="flow-radio-v">
                <el-radio-group
                  v-model="curNode.property.rejectType"
                  size="small"
                  @change="curNodeChange"
                >
                  <el-radio
                    v-for="(val, key) in REJECT_TYPE"
                    :key="key"
                    :label="key"
                    >{{ val }}</el-radio
                  >
                </el-radio-group>
              </div>
              <p class="property-desc">驳回后提交方式</p>
              <div class="flow-radio-v">
                <el-radio-group
                  v-model="curNode.property.rejectResubmitType"
                  size="small"
                  @change="curNodeChange"
                >
                  <el-radio
                    v-for="(val, key) in REJECT_RESUBMIT_TYPE"
                    :key="key"
                    :label="key"
                    >{{ val }}</el-radio
                  >
                </el-radio-group>
              </div>
            </div>
            <el-button size="mini" type="danger" plain @click="toDeleteNode"
              >删除节点</el-button
            >
          </div>
        </div>
      </div>
    </el-dialog>

    <!-- SelectUserDialog -->
    <select-user-dialog
      ref="SelectUserDialog"
      :users="curAddUsers"
      @modified="userModified"
    ></select-user-dialog>
    <!-- SelectRoleDialog -->
    <select-role-dialog
      ref="SelectRoleDialog"
      :data="curAddRoles"
      @modified="roleModified"
    ></select-role-dialog>
  </div>
</template>

<script>
import { deepCopy } from "../../../plugins/utils";
import { flowDetail, updateFlowDetail } from "../api";
import SelectUserDialog from "./SelectUserDialog";
import SelectRoleDialog from "./SelectRoleDialog";
import { FLOW_MODEL_TYPE } from "../../../constants/enumerate";

const initFlowInfo = {
  id: null,
  name: "",
  type: "ELECTRON_FLOW",
  modelType: "USER_FIXED"
};

const DEFAULT_NODE = {
  id: "",
  type: "PROCESS", // 节点类型，START：开始节点，PROCESS：过程节点，END：结束节点
  content: "",
  w: 150,
  h: 40,
  x: 0,
  y: 0,
  property: {
    approveUserType: "USER", // 审批用户类型，USER：成员,ROLE：角色
    approveUsers: [], // 审批用户列表
    approveRoles: [], // 审批角色列表
    copyForUsers: [], // 抄送用户列表
    multipleUserApproveType: "ORDER", // 审批用户类别，ORDER：依次审批，ALL：会签（所有人必须审批），SOME：或签（一名审批人同意或拒绝即可）
    rejectType: "PREV", // 驳回类型，PREV：上一节点，START：发起人节点，PREV_ALL：该节点前全部节点
    rejectResubmitType: "NORMAL", // 驳回再提交类型，NORMAL：按正常流程提交，PREV_STEP：提交到驳回节点
    approveUserCountType: "ONE", // 选择方式，ONE:一个，MORE:多个
    approveUserSelectRange: "ALL", // 选择范围，ALL:全单位，ROLE:角色
    approveUserSelectRoles: [] // 指定角色范围
  }
};
// 详细参数：https://doc.qmth.com.cn/pages/viewpage.action?pageId=40435764

export default {
  name: "modify-flow-detail",
  components: { SelectUserDialog, SelectRoleDialog },
  props: {
    instance: {
      type: Object,
      default() {
        return {};
      }
    }
  },
  data() {
    return {
      modalIsShow: false,
      isSubmit: false,
      FLOW_MODEL_TYPE,
      initNodes: [
        {
          id: "1",
          type: "START",
          content: "开始流程",
          w: 150,
          h: 40,
          x: 0,
          y: 0,
          property: null
        },
        {
          id: "2",
          type: "END",
          content: "结束流程",
          w: 150,
          h: 40,
          x: 0,
          y: 0,
          property: null
        }
      ],
      flowInfo: { ...initFlowInfo },
      nodes: [],
      curNode: {},
      curAddUsers: [],
      curAddUserType: "",
      curAddRoles: [],
      curAddRoleType: "",
      nodeIcons: {
        START: "el-icon-video-play",
        END: "el-icon-switch-button",
        PROCESS: "el-icon-circle-plus-outline"
      },
      APPROVE_USER_TYPE: {
        USER: "成员",
        ROLE: "角色"
      },
      MULTIPLE_USER_APPROVE_TYPE: {
        ORDER: "依次审批",
        ALL: "会签（所有人必须审批）",
        SOME: "或签（一名审批人同意或拒绝即可）"
      },
      REJECT_TYPE: {
        PREV: "上一节点",
        START: "发起人节点",
        PREV_ALL: "该节点前全部节点"
      },
      REJECT_RESUBMIT_TYPE: {
        NORMAL: "按正常流程提交",
        PREV_STEP: "提交到驳回节点"
      },
      APPROVE_USER_COUNT_TYPE: {
        ONE: "一次选择一个人",
        MORE: "一次选择多个人"
      },
      APPROVE_USER_SELECT_RANGE: {
        ALL: "全单位",
        ROLE: "指定角色"
      },
      rules: {
        modelType: [
          {
            required: true,
            message: "请选择流程指定审批人类型",
            trigger: "change"
          }
        ]
      }
    };
  },
  computed: {
    IS_APPROVE_SET() {
      return this.flowInfo.modelType === "APPROVE_SET";
    }
  },
  methods: {
    async initData(val) {
      if (val.id) {
        const data = await flowDetail(val.id);
        this.flowInfo = this.$objAssign(initFlowInfo, data);
        this.flowInfo.id = data.customFlowId;
        this.nodes = data.customFlowLists;
        this.toSelectNode(this.nodes[1]);
      } else {
        this.flowInfo = this.$objAssign(initFlowInfo, val);
        this.initFlowNodes();
      }
    },
    initFlowNodes() {
      this.nodes = deepCopy(this.initNodes);
      this.toAddNode(this.nodes[0].id);
    },
    visibleChange() {
      this.initData(this.instance);
    },
    cancel() {
      this.modalIsShow = false;
    },
    open() {
      this.modalIsShow = true;
    },
    getDefaultNode() {
      const nodeId = this.nodes.length
        ? Math.max.apply(
            null,
            this.nodes.map(item => item.id)
          ) + 1
        : 1;
      return { ...deepCopy(DEFAULT_NODE), id: nodeId };
    },
    toAddNode(curNodeId) {
      const newNode = this.getDefaultNode();
      const pos = this.nodes.findIndex(node => node.id === curNodeId);
      this.nodes.splice(pos + 1, 0, newNode);
      this.toSelectNode(newNode);
    },
    toDeleteNode() {
      const pos = this.nodes.findIndex(node => node.id === this.curNode.id);
      this.nodes.splice(pos, 1);
      if (this.nodes[pos] && this.nodes[pos].type === "PROCESS") {
        this.toSelectNode(this.nodes[pos]);
      } else {
        let prevPos = pos - 1;
        prevPos = Math.max(prevPos, 0);
        this.toSelectNode(this.nodes[prevPos]);
      }
    },
    toSelectNode(node) {
      if (node.type === "START" || node.type === "END") {
        this.curNode = {};
        return;
      }
      this.curNode = node ? deepCopy(node) : {};
    },
    curNodeChange() {
      const pos = this.nodes.findIndex(node => node.id === this.curNode.id);
      this.nodes.splice(pos, 1, deepCopy(this.curNode));
    },
    // approveUser
    toAddUser(curAddUserType) {
      this.curAddUserType = curAddUserType;
      this.curAddUsers = this.curNode.property[this.curAddUserType];
      this.$refs.SelectUserDialog.open();
    },
    userModified(users) {
      this.curNode.property[this.curAddUserType] = users;
      this.curNodeChange();
    },
    deleteApproveUser(curAddUserType, user) {
      console.log(user);
      const pos = this.curNode.property[curAddUserType].findIndex(
        item => item.id === user.id
      );
      this.curNode.property[curAddUserType].splice(pos, 1);
      this.curNodeChange();
    },
    clearApproveUsers(curAddUserType) {
      this.curNode.property[curAddUserType] = [];
      this.curNodeChange();
    },
    // approveRole
    toAddApproveRole(curAddRoleType) {
      this.curAddRoleType = curAddRoleType;
      this.curAddRoles = this.curNode.property[this.curAddRoleType];
      this.$refs.SelectRoleDialog.open();
    },
    roleModified(roles) {
      this.curNode.property[this.curAddRoleType] = roles;
      this.curNodeChange();
    },
    deleteApproveRole(curAddRoleType, role) {
      const pos = this.curNode.property[curAddRoleType].findIndex(
        item => item.id === role.id
      );
      this.curNode.property[curAddRoleType].splice(pos, 1);
      this.curNodeChange();
    },
    clearApproveRole(curAddRoleType) {
      this.curNode.property[curAddRoleType] = [];
      this.curNodeChange();
    },
    checkData() {
      if (!this.nodes.some(node => node.type === "PROCESS")) {
        this.$message.error("请设置过程节点");
        return;
      }

      if (this.IS_APPROVE_SET) {
        const nodeUserValid = !this.nodes
          .filter(node => node.type === "PROCESS")
          .some(node => {
            if (node.property.approveUserSelectRange === "ROLE") {
              return !node.property.approveUserSelectRoles.length;
            } else {
              return false;
            }
          });
        if (!nodeUserValid) {
          this.$message.error("请完成节点设置");
          return;
        }
      } else {
        const nodeUserValid = !this.nodes
          .filter(node => node.type === "PROCESS")
          .some(node => {
            if (node.property.approveUserType === "USER") {
              return !node.property.approveUsers.length;
              // return !(
              //   node.property.approveUsers.length &&
              //   node.property.copyForUsers.length
              // );
            } else {
              return !node.property.approveRoles.length;
            }
          });
        if (!nodeUserValid) {
          this.$message.error("请完成节点设置");
          return;
        }
      }

      return true;
    },
    async submit() {
      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
      if (!valid) return;

      if (!this.checkData()) return;

      if (this.isSubmit) return;
      const result = await this.$confirm(
        `确定要发布流程【${this.instance.name}】吗?`,
        "提示",
        {
          type: "warning"
        }
      ).catch(() => {});
      if (result !== "confirm") return;

      this.nodes.forEach(node => {
        const dom = document.getElementById(`node-${node.id}`);
        node.w = dom.clientWidth;
        node.h = dom.clientHeight;
        node.x = dom.offsetLeft;
        node.y = dom.offsetTop;
      });

      const nodes = this.nodes.map((node, index) => {
        let nnode = deepCopy(node);
        nnode.id = index + 1;
        if (node.property) {
          if (this.IS_APPROVE_SET) {
            if (node.property.approveUserSelectRange === "ALL") {
              node.property.approveUserSelectRoles = [];
            }
          } else {
            if (node.property.approveUserType === "USER") {
              nnode.approveRoles = [];
            } else {
              nnode.approveUsers = [];
            }
          }
        }

        return nnode;
      });

      this.isSubmit = true;

      const res = await updateFlowDetail({
        customFlowId: this.flowInfo.id,
        name: this.flowInfo.name,
        type: this.flowInfo.type,
        modelType: this.flowInfo.modelType,
        publish: true,
        customFlowLists: nodes
      }).catch(() => {});
      this.isSubmit = false;
      if (!res) return;

      this.$message.success("编辑成功！");
      this.$emit("modified");
      this.cancel();
    }
  }
};
</script>
