<template>
  <a-modal :visible="visible" destroy-on-close :width="800" @ok="handleOk" @cancel="closeModal">
    <a-tabs>
      <a-tab-pane key="1" tab="基础属性">
        <a-form-model
          :class="$style.form"
          :model="form"
          :label-col="{ span: 5 }"
          :wrapper-col="{ span: 18 }"
        >
          <div :class="$style.border">
            <a-form-model-item label="方式">
              <a-radio-group
                v-model="updateNameType"
                :options="updateNameTypeOptions"
                @change="nameTypeChange"
              />
            </a-form-model-item>
            <a-form-model-item v-if="updateNameType === 'update'" label="名称">
              <a-input v-model="form.name" />
            </a-form-model-item>
            <a-form-model-item v-if="updateNameType === 'replace'" label="从名称查找">
              <a-input v-model="form.replaceName" />
            </a-form-model-item>
            <a-form-model-item v-if="updateNameType === 'replace'" label="替换为">
              <a-input v-model="form.name" />
            </a-form-model-item>
          </div>
          <div v-if="mode === 'flow'" :class="$style.border">
            <a-form-model-item label="上级分类">
              <sd-tree-picker
                v-model="categoryId"
                :load-tree-data="loadTreeData"
                single
                option-value="id"
                option-label="text"
              />
            </a-form-model-item>
          </div>
        </a-form-model>
      </a-tab-pane>
      <a-tab-pane v-if="mode !== 'flow'" key="2" tab="参与者">
        <a-form-model-item
          :label="mode === 'node' ? '参与者处理方式' : '参与者选择方式'"
          :label-col="{ span: 5 }"
          :wrapper-col="{ span: 12 }"
        >
          <a-select
            v-model="form.strategy"
            :class="$style.select"
            :options="mode === 'node' ? strategyOptions : strategySelectorOptions"
          />
        </a-form-model-item>
        <sd-participant-form v-if="mode === 'node'" @change="participantChange" />
      </a-tab-pane>
      <a-tab-pane v-if="mode === 'node'" key="3" tab="字段权限">
        <a-table :data-source="dataSource" :columns="columns" bordered>
          <a-radio-group
            slot="readonly"
            slot-scope="text, record"
            @change="(e) => readonlyChange(e, record)"
          >
            <a-radio :value="false">是</a-radio>
            <a-radio :value="true">否</a-radio>
          </a-radio-group>
          <a-radio-group
            slot="mandatory"
            v-model="record.mandatory"
            slot-scope="text, record"
            :disabled="record.readonly"
          >
            <a-radio :value="true">是</a-radio>
            <a-radio :value="false">否</a-radio>
          </a-radio-group>
        </a-table>
      </a-tab-pane>
      <a-tab-pane v-if="mode === 'flow'" key="4" tab="流程操作">
        <sd-flowaction-form
          v-for="item in flowAction"
          :key="item.id"
          :mode="mode"
          :form="item"
          @change="formChange"
        />
        <div v-if="mode === 'flow'" :class="$style.border">
          <a-form-model :label-col="{ span: 8 }" :wrapper-col="{ span: 13 }">
            <a-form-model-item label="允许驳回">
              <a-radio-group v-model="isReback" @change="setRebackType">
                <a-radio value="yes">是</a-radio>
                <a-radio value="no">否</a-radio>
              </a-radio-group>
            </a-form-model-item>
            <a-form-model-item v-if="isReback === 'yes'" label="驳回方式">
              <a-select
                v-model="formProps._grcv5_reback_type_type"
                :class="$style.select"
                :options="rebacktypeOptions"
                @change="rebacktypeChange"
              />
            </a-form-model-item>
            <a-form-model-item v-if="isReback === 'yes'" label="驳回后再次提交路径">
              <a-select v-model="rebackpath" mode="multiple" :options="rebackpathOptions" />
            </a-form-model-item>
          </a-form-model>
        </div>
      </a-tab-pane>
      <a-tab-pane v-if="mode === 'flow'" key="5" tab="工作日历">
        <a-table :columns="worklogColumns" :data-source="workLogData" bordered size="middle">
          <a-checkbox
            slot="action"
            v-model="record.checked"
            slot-scope="text, record"
            @change="(e) => worklogChange(e, record)"
          />
        </a-table>
      </a-tab-pane>
      <a-tab-pane v-if="mode === 'node'" key="6" tab="业务属性">
        <div v-for="(item, key, index) in businessAttr" :key="index">
          <h2>{{ key }}</h2>
          <a-descriptions bordered :column="2" :class="$style.attrDesc" size="small">
            <a-descriptions-item
              v-for="(codeItem, codeIndex) in item"
              :key="codeIndex"
              :label="codeItem.label"
            >
              <a-radio-group @change="(e) => busiAttrChange(e, codeItem)">
                <a-radio :value="true">是</a-radio>
                <a-radio :value="false">否</a-radio>
              </a-radio-group>
            </a-descriptions-item>
          </a-descriptions>
        </div>
      </a-tab-pane>
      <a-tab-pane key="7" tab="处理规则">
        <div v-if="mode !== 'node'" :class="$style.border">
          <a-form-model-item
            :label="mode === 'line' ? '自动提交' : '撤回留痕'"
            :label-col="{ span: 8 }"
            :wrapper-col="{ span: 13 }"
          >
            <a-radio-group
              v-model="formProps[mode === 'line' ? 'autoSubmit' : 'PRODUCT_CANCEL_TRACE']"
            >
              <a-radio :value="true">是</a-radio>
              <a-radio :value="false">否</a-radio>
            </a-radio-group>
          </a-form-model-item>
        </div>
        <sd-flowaction-form
          v-if="mode !== 'line'"
          :mode="mode"
          :form="handleRule.find((h) => h.showMode === mode)"
          @change="formChange"
        />
        <sd-time-limit v-if="mode === 'node'" ref="timeLimit" />
      </a-tab-pane>
    </a-tabs>
  </a-modal>
</template>

<script>
import { Message, Modal } from 'ant-design-vue'
import FlowamendService from './flowamend-service'
import components from './_import-components/sd-flowamend-modal-import'
const deepClone = (obj, newObj) => {
  const cloneObj = newObj || {}
  for (const key in obj) {
    if (obj[key] && obj[key].constructor === Object) {
      cloneObj[key] = {}
      deepClone(obj[key], cloneObj[key])
    } else {
      cloneObj[key] = obj[key]
    }
  }
  return cloneObj
}

const columns = [
  {
    title: '字段',
    dataIndex: 'field',
    key: 'field',
    width: '50%',
    align: 'center',
  },
  {
    title: '可编辑',
    dataIndex: 'readonly',
    key: 'readonly',
    align: 'center',
    scopedSlots: { customRender: 'readonly' },
  },
  {
    title: '必填',
    dataIndex: 'mandatory',
    key: 'mandatory',
    align: 'center',
    scopedSlots: { customRender: 'mandatory' },
  },
]
const worklogColumns = [
  {
    dataIndex: 'action',
    key: 'action',
    scopedSlots: { customRender: 'action' },
  },
  {
    title: '日历编码',
    dataIndex: 'calendarCode',
    key: 'calendarCode',
  },
  {
    title: '日历名称',
    dataIndex: 'calendarName',
    key: 'calendarName',
  },
  {
    title: '包含年份',
    dataIndex: 'includeYears',
    key: 'includeYears',
  },
  {
    title: '所属机构',
    dataIndex: 'orgName',
    key: 'orgName',
  },
]
export default {
  name: 'SdFlowamendModal',
  metaInfo: {
    title: 'SdFlowamendModal',
  },
  components,
  props: {
    mode: {
      type: String,
      default: 'node',
    },
  },
  data() {
    return {
      visible: false,
      updateNameType: 'update',
      rebackpath: [],
      categoryId: [],
      isReback: '',
      updateNameTypeOptions: [
        { label: '修改', value: 'update' },
        { label: '替换', value: 'replace' },
      ],
      rebacktypeOptions: [
        { label: '全部环节', value: 'all' },
        { label: '到上一环节', value: 'previous' },
      ],
      rebackpathOptions: [
        { label: '驳回重走', value: 'rework' },
        { label: '驳回直送', value: 'jumpto' },
      ],

      baseForm: {
        categoryId: null,
        replaceName: null,
        name: null,
        strategy: null,
        allowTurnTodo: null,
        allowInform: null,
        informType: null,
      },
      busiProps: {},
      formProps: {},
      dataSource: [{ field: '审批意见', id: 'approveOpinion', readonly: null, mandatory: null }],
      strategyOptions: [
        { label: '参与者并行', value: 'parallel' },
        { label: '参与者串行', value: 'serial' },
        { label: '单一参与者', value: 'single' },
      ],
      strategySelectorOptions: [
        { label: '单选', value: '单选' },
        { label: '多选', value: '多选' },
      ],
      columns,
      worklogColumns,
      workLogData: [],
      flowAction: [
        { label: '是否允许转办', id: 'allowTurnTodo', mode: null, value: null },
        {
          label: '是否允许知会',
          id: 'allowInform',
          mode: null,
          value: null,
          informType: null,
        },
      ],
      handleRule: [
        {
          label: '同处理人跳过',
          id: 'skipSameUser',
          mode: null,
          value: null,
          notShowSkipStep: null,
          showMode: 'node',
        },
        {
          label: '乐观锁',
          id: 'optimisticLock',
          mode: null,
          value: true,
          showMode: 'flow',
        },
      ],
      lineHanleRule: [
        { label: '是', value: true },
        { label: '否', value: false },
      ],
      businessAttr: {},
      form: {},
    }
  },
  computed: {
    formLabelList() {
      const labelObj = {
        updateNameType: '名称修改方式',
        categoryId: '上级分类',
        replaceName: '从名称查找',
        name: this.updateNameType === 'update' ? '名称' : '名称替换',
        strategy: this.mode === 'node' ? '参与者处理方式' : '参与者选择方式',
        allowTurnTodo: '是否允许转办',
        allowInform: '是否允许知会',
        informType: '知会方式',
        PRODUCT_CANCEL_TRACE: '撤回留痕',
        optimisticLock: '乐观锁',
        autoSubmit: '自动提交',
        _grcv5_reback_type_type: '是否允许驳回',
        _grcv5_reback_type_path: '驳回后再次提交路径',
        skipSameUser: '同处理人跳过',
        notShowSkipStep: '不显示跳过节点',
        mandatory: '审批意见必填',
        editor: '审批意见可编辑',
        _grcv5_workcalendar_name: '工作日历',
        participants: '候选参与者',
        defaultParticipants: '默认参与者',
      }
      const busiAttrLabelList = Object.values(this.businessAttr)
        .flat()
        .reduce((res, item) => {
          res = { ...res, ...{ [item.code]: item.label } }
          return res
        }, {})
      return { ...labelObj, ...busiAttrLabelList }
    },
    formValuelist() {
      return [
        ...this.strategyOptions,
        ...this.rebackpathOptions,
        ...this.strategySelectorOptions,
        ...this.lineHanleRule,
        ...this.updateNameTypeOptions,
        ...this.rebacktypeOptions,
        ...this.rebackpathOptions,
        ...[
          { label: '打开待阅变已阅', value: 'openRead' },
          { label: '点击反馈变已阅', value: 'clickRead' },
          { label: '系统全局设置', value: '' },
          { label: this.categoryId[0]?.text, value: this.categoryId[0]?.id.slice(1) },
          {
            label: this.workLogData.filter((item) => item.checked)[0]?.calendarName,
            value: this.workLogData.filter((item) => item.checked)[0]?.calendarName,
          },
          {
            label: this.form.participants?.map((p) => p.name || p.text)?.join(),
            value: this.form.participants,
          },
          {
            label: JSON.parse(this.formProps.defaultParticipants || '[]')
              ?.map((p) => p.name || p.text)
              ?.join(),
            value: this.formProps.defaultParticipants,
          },
        ],
      ]
    },
  },
  created() {
    this.resetData()
    this.getWorkLog()
    this.getAppSetting()
  },
  methods: {
    participantChange(val) {
      this.form.participants = val.participants
      if (val.defaultParticipants) {
        this.formProps.defaultParticipantsStrategy = 'range'
        this.formProps.defaultParticipants = JSON.stringify(val.defaultParticipants)
      } else {
        this.formProps.defaultParticipantsStrategy = null
        this.formProps.defaultParticipants = null
      }
    },
    getAppSetting() {
      FlowamendService.getAppSetting().then((res) => {
        if (res.data) {
          const data = res.data
          const list = [...this.flowAction, ...this.handleRule]
          list.forEach((item) => {
            if (Object.keys(data).indexOf(item.id) > -1) {
              item.globalValue = data[item.id]
            }
          })
        }
      })
    },
    nameTypeChange() {
      if (this.updateNameType === 'update') this.form.replaceName = null
      this.form.updateNameType = this.updateNameType
    },
    busiAttrChange(e, codeItem) {
      codeItem.value = e.target.value
      this.busiProps = { ...this.busiProps, ...{ [codeItem.code]: codeItem.value } }
    },
    rebacktypeChange(val) {
      this.rebackpath = val === 'all' ? this.rebackpathOptions.map((item) => item.value) : []
    },
    setRebackType() {
      this.formProps._grcv5_reback_type_type = this.isReback === 'no' ? this.isReback : 'all'
    },
    resetData() {
      this.dataSource.forEach((item) => {
        item.readonly = null
        item.mandatory = null
      })
      Object.assign(this, {
        rebackpath: [],
        isReback: '',
        formProps: {},
        busiProps: {},
        form: deepClone(this.baseForm),
        updateNameType: 'update',
        categoryId: [],
      })
    },
    readonlyChange(e, record) {
      record.readonly = e.target.value
      if (record.readonly && record.mandatory) record.mandatory = false
      this.$set(this.dataSource, this.dataSource.indexOf(record), record)
    },

    getWorkLog() {
      const params = {
        expressions: [],
        startPosition: 0,
        maxResults: -1,
        orderBy: 'calendarCode desc',
      }
      FlowamendService.getWorklogList(params).then((res) => {
        if (res.datas) {
          res.datas.forEach((item) => {
            item.checked = false
          })
          this.workLogData = res.datas
        }
      })
    },
    worklogChange(e, record) {
      this.workLogData.forEach((item) => (item.checked = false))
      record.checked = e.target.checked
      this.$set(
        this.workLogData,
        this.workLogData.findIndex((item) => item.id === record.id),
        record
      )
    },
    loadTreeData(parentId) {
      return FlowamendService.getTreeNode({ parentCatId: parentId || '' }).then((res) => {
        if (res.data) {
          res.data.forEach((item) => {
            item.isLeaf = item.leaf
          })
          return res.data
        }
      })
    },
    getBusinessAttr() {
      FlowamendService.getBusinessAttr({ attrUseType: 'NODE' }).then((res) => {
        if (res.length) {
          this.businessAttr = res
            .map((r) => r.flowCategory)
            .reduce((total, item, i) => {
              total[item] = [
                ...(total[item] || []),
                {
                  label: res[i].attrName,
                  code: res[i].attrCode,
                  value: null,
                },
              ]
              return total
            }, {})
        }
      })
    },
    formChange(formItem) {
      const attrName =
        ['allowTurnTodo', 'allowInform'].indexOf(formItem.id) > -1 ? 'form' : 'formProps'
      const newAttr = Object.keys(formItem)
        .filter(
          (key) => ['id', 'label', 'mode', 'showMode'].indexOf(key) === -1 && formItem[key] !== null
        )
        .reduce((res, item) => {
          res =
            item === 'value'
              ? { ...res, ...{ [formItem.id]: formItem.value } }
              : { ...res, ...{ [item]: formItem[item] } }
          return res
        }, {})
      this[attrName] = { ...this[attrName], ...newAttr }
    },
    open() {
      this.resetData()
      this.visible = true
      this.getBusinessAttr()
    },
    closeModal() {
      this.visible = false
    },
    handleOk() {
      if (this.rebackpath.length) this.formProps._grcv5_reback_type_path = this.rebackpath.join()
      if (this.categoryId?.length) this.form.categoryId = this.categoryId[0].id.slice(1)
      const calendar = this.workLogData.filter((item) => item.checked)
      if (calendar.length) {
        this.formProps._grcv5_workcalendar_name = calendar[0].calendarName
        this.formProps._grcv5_workcalendar_code = calendar[0].calendarCode
      }
      const hasValueForm = Object.values({ ...this.form, ...this.formProps }).some(
        (value) => value !== null
      )
      const formFields = this.dataSource
        .filter((item) => item.readonly !== null || item.mandatory !== null)
        .reduce((res, item) => {
          return {
            ...res,
            [item.id]: { readonly: item.readonly, mandatory: item.mandatory },
          }
        }, {})
      const hasValueBuis = Object.keys(this.busiProps).length
      const timeLimitForm = this.$refs.timeLimit?.allForm()
      if (timeLimitForm?.errorCode) {
        Message.warn(
          timeLimitForm.errorCode === 1 ? '到期时限必须设置' : '时限值不能设置负数，请重新设置'
        )
        return
      }
      if (hasValueBuis || Object.keys(formFields).length || hasValueForm || timeLimitForm) {
        Object.assign(this.form, {
          busiProps: Object.keys(this.busiProps).length ? this.busiProps : null,
          props: Object.keys(this.formProps).length ? this.formProps : null,
          fields: Object.keys(formFields).length ? formFields : null,
          updateNameType: this.form.name || this.form.replaceName ? this.updateNameType : null,
          timer: timeLimitForm,
        })
        this.secondConfirm()
      } else Message.warn('您还没有修改任何属性')
    },
    secondConfirm() {
      const timeConfirmText = this.$refs.timeLimit?.confirmText() || []
      const field = { ...this.form.fields?.approveOpinion } || {}
      if ([null, undefined].indexOf(field.readonly) === -1) field.editor = !field.readonly
      const form = { ...this.form, ...this.formProps, ...this.busiProps, ...field }
      const formConfirmText = Object.keys(form)
        .filter((key) => Object.keys(this.formLabelList).indexOf(key) > -1 && form[key] !== null)
        .map((item) => {
          return {
            label: this.formLabelList[item],
            value: this.formValuelist.find((l) => l.value === form[item])?.label || form[item],
          }
        })
        .concat(timeConfirmText)
      Modal.confirm({
        title: '确认批量修改以下属性吗?',
        width: 500,
        content: () => {
          return [
            <div>
              {formConfirmText.map((item) => {
                return [
                  <div>
                    <span>【{item.label}】</span> 为<span>'{item.value}'</span>
                  </div>,
                ]
              })}
            </div>,
          ]
        },
        onOk: () => {
          this.$emit('ok', this.form)
        },
      })
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
.title-text {
  margin-left: 10px;
}

.attr-desc {
  tr {
    td {
      width: 150px;
    }
  }
}
.select {
  min-width: 120px;
}
.border {
  width: 70%;
  padding: 10px;
  margin: 0 auto 20px;
  border: 1px solid #ccc;
  :global .ant-row {
    margin-bottom: 15px;
  }
}
</style>
