<template>
  <div>
    <el-dialog :close-on-click-modal="false" class="flow-step-drawer" :title="title" :visible.sync="visible" :before-close="handleBeforeClose">
      <el-steps v-show="list.length" :space="200" finish-status="success" style="padding:16px;padding-top:0px;">
        <el-step v-for="item in list" :key="item.id" status="finish" :title="item.name">
          <div slot="description">
            <div>审核人: {{ item.userNames || '无' }}</div>
            <div>审核角色：{{ item.roleNames.join(',') || '无' }}</div>
            <div>备注：{{ item.note }}</div>
          </div>
        </el-step>
      </el-steps>
      <el-button
        v-if="$requirePermission('XT.SH.U')"
        v-waves
        type="primary"
        icon="el-icon-circle-plus-outline"
        size="small"
        @click="handleCreate"
      >新增步骤</el-button>
      <el-table v-loading="listLoading" row-key="id" class="m-t-10" :data="list" height="300px" border fit highlight-current-row>
        <el-table-column label="顺序" prop="index" align="center" width="60" />
        <el-table-column label="名称" prop="name" align="center" />
        <el-table-column label="审核人" prop="userNames" align="center" />
        <el-table-column label="审核角色" prop="roleNames" align="center">
          <!-- <template slot-scope="{ row }">
            <el-popover
              placement="right"
              width="400"
              trigger="click"
              @show="handleRole(row.roleName)"
            >
              <strong>{{ row.roleName }}</strong>包含用户：
              <ul
                class="m-t-5"
                :data="roleUsers"
                height="400px"
                border
                v-loading="roleUserLoading"
                style="max-height:400px;overflow-y:scroll;list-style-type:none;padding-left:10px;"
              >
                <li :key="u.id" v-for="(u, i) in roleUsers">{{ i + 1 }}, {{ u.name }}</li>
              </ul>
              <el-button slot="reference" type="text" size="mini">
                {{
                row.roleName
                }}
              </el-button>
            </el-popover>
          </template>-->
        </el-table-column>
        <el-table-column label="操作" align="center" width="160px" class-name="small-padding">
          <template slot-scope="{ row }">
            <el-popover :ref="'popover-' + row.id" placement="top" width="160" trigger="manual">
              <p>确定删除吗？</p>
              <div style="text-align: right; margin: 0">
                <el-button v-waves size="mini" type="text" @click="cancelDelete(row.id)">取消</el-button>
                <el-button v-waves type="primary" size="mini" @click="deleteData(row)">确定</el-button>
              </div>
              <el-button v-if="$requirePermission('XT.SH.U')" slot="reference" size="mini" type="danger" @click="handleDelete(row.id)">删除</el-button>
            </el-popover>
            <!-- <el-button size="mini" type="danger" @click="handleDelete(row)">删除</el-button> -->
            <el-button v-if="$requirePermission('XT.SH.U')" v-waves size="mini" type="primary" @click="handleUpdate(row)">修改</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>
    <el-dialog :close-on-click-modal="false" :title="textMap[formStatus]" :visible.sync="formVisible">
      <el-form ref="dataForm" v-loading="listLoading" :rules="rules" :model="step" label-position="right" label-width="80px">
        <el-row>
          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
            <el-form-item label="名称" prop="name" class="form-item">
              <el-input v-model="step.name" />
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
            <el-form-item label="顺序" prop="index" class="form-item">
              <el-input-number v-model="step.index" :min="1" :max="99" class="w100p" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
            <el-form-item label="审核人" prop="userIds" class="form-item">
              <el-select v-model="step.userIds" clearable filterable multiple class="w100p">
                <el-option v-for="item in users" :key="item.id" :value="item.id" :label="item.name + '(' + item.userName + ')'" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
            <el-form-item label="审核角色" prop="roleNames" class="form-item">
              <el-select v-model="step.roleNames" clearable filterable multiple class="w100p">
                <el-option v-for="item in roles" :key="item.id" :value="item.name" :label="item.name" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="备注" prop="note" class="form-item">
              <el-input v-model="step.note" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="条件" prop="conditionType">
              <el-radio-group v-model="step.conditionType">
                <el-radio :value="1" :label="1">满足全部条件</el-radio>
                <el-radio :value="2" :label="2">满足任一条件</el-radio>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="条件列表" prop="conditions">
              <div>
                <el-button type="primary" size="mini" @click="addCondition">新增条件</el-button>
                <el-table border stripe :data="step.conditions">
                  <el-table-column label="序号" type="index" width="80px" />
                  <el-table-column label="名称">
                    <template slot-scope="{ row }">
                      <el-select v-model="row.fieldId" @change="changeField(row, $event)">
                        <el-option v-for="item in conditionFields" :key="item.id" :label="item.name" :value="item.id" />
                      </el-select>
                    </template>
                  </el-table-column>
                  <el-table-column label="条件">
                    <template slot-scope="{ row }">
                      <match-type-select v-model="row.matchType" />
                    </template>
                  </el-table-column>
                  <el-table-column label="值">
                    <template slot-scope="{ row }">
                      <field-value-select v-if="row.field" v-model="row.value" :project-id="projectId" :data-url="row.field.dataUrl" />
                    </template>
                  </el-table-column>
                  <el-table-column label="操作">
                    <template slot-scope="{ row }">
                      <el-button type="danger" size="mini" @click="deletCondition(row)">删除</el-button>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button v-waves type="danger" size="small" icon="el-icon-circle-close" @click="handleCancel">取消</el-button>
        <el-button
          v-waves
          type="primary"
          size="small"
          icon="el-icon-circle-check"
          @click="formStatus === 'create' ? createData() : updateData()"
        >保存</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import * as flowApi from '@/api/audit-flow'
import * as userApi from '@/api/backbone/user'
import * as roleApi from '@/api/backbone/role'
import waves from '@/directive/waves' // waves directive
import { deepClone } from '@/utils'
import MatchTypeSelect from './MatchTypeSelect'
import FieldValueSelect from './FieldValueSelect'

export default {
  directives: { waves },
  components: { MatchTypeSelect, FieldValueSelect },
  props: {
    projectId: {
      type: String,
      default: ''
    },
    title: {
      type: String,
      default: ''
    },
    flowId: {
      type: String,
      default: ''
    },
    value: {
      type: Boolean,
      default: false
    },
    conditionFields: {
      type: Array,
      default: function() {
        return []
      }
    }
  },
  data() {
    var validateConditions = (rule, value, callback) => {
      if (!this.step.conditions || this.step.conditions.length === 0) {
        callback()
        return
      }

      var hasInvalidCondition = this.step.conditions.find(t => !t.fieldId || !t.matchType || !t.value)

      if (hasInvalidCondition) {
        callback(new Error('存在无效的条件'))
      } else {
        callback()
      }
    }

    var validateUserRole = (rule, value, callback) => {
      if (!this.step.userIds && !this.step.roleNames) {
        callback(new Error('请选择审核人或审核角色'))
      } else {
        callback()
      }
    }

    return {
      users: [],
      roles: [],
      roleName: '',
      roleUsers: [],
      roleUserLoading: false,
      visible: false,
      delVisible: false,
      listLoading: false,
      list: [],
      step: {
        id: undefined,
        name: undefined,
        conditions: []
      },
      deleteId: undefined,
      formVisible: false,
      formStatus: '',
      textMap: {
        update: '修改步骤',
        create: '创建步骤'
      },
      rules: {
        name: [
          { required: true, message: '名称是必须的', trigger: 'blur' },
          {
            min: 2,
            max: 64,
            message: '长度在 2 到 64 个字符',
            trigger: 'blur'
          }
        ],
        index: [{ required: true, message: '请输入顺序', trigger: 'blur' }],
        userIds: [{ validator: validateUserRole, trigger: 'change' }],
        roleNames: [{ validator: validateUserRole, trigger: 'change' }],
        conditions: [{ validator: validateConditions, trigger: 'blur' }]
      }
    }
  },
  watch: {
    value(val) {
      this.visible = val
    },
    visible(val) {
      this.$emit('input', val)
    },
    flowId(newVal) {
      if (newVal) {
        this.getList()
      } else {
        this.list = []
      }
    },
    roleName(val) {
      if (val) {
        this.getRoleUsers()
      } else {
        this.roleUsers = []
      }
    }
  },
  created() {
    userApi.lookupAll().then(res => {
      this.users = res
    })
    roleApi.lookupAll().then(res => {
      this.roles = res
    })
  },
  methods: {
    addCondition() {
      var condition = { index: this.step.conditions.length + 1 }
      if (this.conditionFields.length) {
        condition.fieldId = this.conditionFields[0].id
        condition.field = this.conditionFields[0]
      }
      this.step.conditions.push(condition)
    },
    deletCondition(row) {
      this.step.conditions = this.step.conditions.filter(t => t.index !== row.index)
    },
    changeField(row, fieldId) {
      row.field = this.conditionFields.find(t => t.id === fieldId)
    },
    getList() {
      this.listLoading = true
      flowApi.getSteps(this.flowId).then(res => {
        res.map(t => {
          t.roleNames = t.roleNames ? t.roleNames.split(',') : []
          t.userIds = t.userIds ? t.userIds.split(',') : []
        })
        this.list = res
        this.listLoading = false
      })
    },
    resetStep() {
      this.step = {
        id: undefined,
        auditFlowId: this.flowId,
        name: undefined,
        conditions: [],
        userIds: [],
        roleNames: []
      }
    },
    handleCreate() {
      this.resetStep()
      this.step.index = this.list.length + 1
      this.formVisible = true
      this.formStatus = 'create'
    },
    handleUpdate(row) {
      this.step = deepClone(row)
      this.formVisible = true
      this.formStatus = 'update'
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    handleBeforeClose(done) {
      this.formVisible = false
      if (this.deleteId) {
        this.cancelDelete(this.deleteId)
      }
      done()
    },
    handleCancel() {
      this.resetStep()
      this.formVisible = false
    },
    createData() {
      this.$refs['dataForm'].validate(valid => {
        if (valid) {
          this.listLoading = true
          this.step.userIds = this.step.userIds ? this.step.userIds.join(',') : ''
          this.step.roleNames = this.step.roleNames ? this.step.roleNames.join(',') : ''
          flowApi.createStep(this.flowId, this.step).then(() => {
            this.getList()
            this.formVisible = false
            this.$notify({
              title: '成功',
              message: '创建成功',
              type: 'success',
              duration: 2000,
              position: 'bottom-right'
            })
          }).finally(() => {
            this.listLoading = false
          })
        }
      })
    },
    updateData() {
      this.$refs['dataForm'].validate(valid => {
        if (valid) {
          this.listLoading = true
          this.step.userIds = this.step.userIds ? this.step.userIds.join(',') : ''
          this.step.roleNames = this.step.roleNames ? this.step.roleNames.join(',') : ''
          flowApi.updateStep(this.flowId, this.step).then(() => {
            this.getList()
            this.formVisible = false
            this.$notify({
              title: '成功',
              message: '修改成功',
              type: 'success',
              duration: 2000,
              position: 'bottom-right'
            })
          }).finally(() => {
            this.listLoading = false
          })
        }
      })
    },
    handleDelete(id) {
      this.deleteId = id
      this.$nextTick(() => {
        this.$refs[`popover-` + id].doShow()
      })
    },
    cancelDelete(id) {
      this.deleteId = undefined
      this.$nextTick(() => {
        this.$refs[`popover-` + id].doClose()
      })
    },
    deleteData(row) {
      flowApi.deleteStep(this.flowId, row.id).then(() => {
        this.cancelDelete(row.id)
        this.getList()
        this.$notify({
          title: '成功',
          message: '删除成功',
          type: 'success',
          duration: 2000,
          position: 'bottom-right'
        })
      })
    },
    handleRole(roleName) {
      this.roleName = roleName
    },
    getRoleUsers() {
      this.roleUserLoading = true
      userApi.lookupByRoleName(this.roleName).then(res => {
        this.roleUsers = res
        this.roleUserLoading = false
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.flow-step-drawer {
  ::v-deep .el-drawer__header {
    margin-bottom: 10px;
  }
}
</style>
