<template>
  <a-spin :spinning="loading" :class="$style.spin">
    <sd-form ref="form" :init-values="initValues">
      <template v-slot="{ model }">
        <table class="sd-form-table">
          <tr v-for="f in initValues" :key="f.name">
            <sd-form-item-td
              :name="f.name"
              :label="f.name === 'methodScript' ? null : undefined"
              :colspan="f.name === 'methodScript' ? 2 : 1"
              :input-props="f.attrFD?.formItemProps?.inputProps || {}"
              @change="(value) => valueChange(value, f.name)"
            >
              <!-- 事件动态表格 -->
              <sd-events-child-table
                v-if="f.name === 'methodScript'"
                v-model="model.methodScript"
                :events-define="visibleEventsDefine"
                :form-id="SdEventsManage.formId"
              />
            </sd-form-item-td>
          </tr>
        </table>
      </template>
    </sd-form>
  </a-spin>
</template>

<script>
import eventHandlers from './event-handlers'
import components from './_import-components/sd-events-backend-form-import'

const flowTriggerMotors = [
  { label: '起草提交', value: '7' },
  { label: '流程结束', value: '8' },
  { label: '回到起草', value: '9' },
]

export default {
  name: 'SdEventsBackendForm',
  components,
  props: {
    eventsDefine: {
      type: Array,
      default: () => [],
    },
    formData: {
      type: Object,
      default: undefined,
    },
  },
  inject: {
    SdEventsManage: { default: () => {} },
  },
  data() {
    return {
      initValues: [
        {
          name: 'methodName',
          caption: '事件名称',
          dataType: 'string',
          required: true,
        },
        {
          name: 'methodCode',
          caption: '事件编码',
          dataType: 'string',
          required: true,
          attr: {
            regex: /^[a-z][a-zA-Z]*$/,
            regexMessage: '必须是字母,建议为驼峰格式，如dataUpdate',
          },
          attrFD: {
            formItemProps: {
              inputProps: {
                placeholder: '请输入字母，建议为驼峰格式，如dataUpdate',
              },
            },
          },
        },
        {
          name: 'methodDesc',
          caption: '事件说明',
          dataType: 'string',
        },
        {
          name: 'triggerMotor',
          caption: '触发时机',
          dataType: 'selectlist',
          attr: {
            selectListItem: [
              { label: '新建', value: '0' },
              { label: '保存', value: '1' },
            ],
          },
          attrFD: {
            popoverDescription: true,
            description: '<p>当前表单进行相关操作时触发事件执行。</p>',
            formItemProps: {
              inputProps: {
                allowClear: true,
              },
            },
          },
        },
        {
          name: 'sortNumber',
          caption: '排序号',
          dataType: 'number',
          attr: {
            controlType: 'NumberType',
            decimalPrecision: '0',
            field: 'sortNumber',
            mandatory: 'false',
            maxValue: '99999',
            minValue: '0',
          },
        },
        {
          name: 'methodScript',
          caption: '触发事件',
          dataType: 'string',
        },
      ],
      loading: true,
      triggerMotor: '',
    }
  },
  computed: {
    // 黑名单
    excludes() {
      // 无流程表单、触发时机为新建时
      if (!this.SdEventsManage.isFlow && this.triggerMotor === '0') {
        return ['create', 'updateData']
      }
      return []
    },
    visibleEventsDefine() {
      return this.eventsDefine.filter((e) => {
        // 过滤事件处理器，黑名单(excludes)中包含了tags中的值，不显示
        return !this.excludes.some((t) => e.module.metaInfo?.tags?.includes?.(t))
      })
    },
  },
  created() {
    // 流程类表单，修改【触发时机】的选项
    if (this.SdEventsManage.isFlow) {
      this.initValues.find((f) => f.name === 'triggerMotor').attr.selectListItem = flowTriggerMotors
    }
    this.initForm()
    // 加载事件定义
    this.loadEventsDefine().then(() => {
      this.loading = false
    })
  },
  methods: {
    validate() {
      return this.$refs.form.validateFields()
    },
    initForm() {
      if (this.formData) {
        this.initValues?.forEach((f) => {
          const value = this.formData[f.name]
          if (f.name === 'triggerMotor') {
            // 触发时机未选择时，后端会存储为-1，前端处理成显示为空
            f.value = value === '-1' ? null : value
            this.triggerMotor = f.value ?? ''
          } else {
            f.value = value && typeof value === 'object' ? JSON.stringify(value) : value
          }
        })
      }
    },
    getSaveData() {
      const formData = {}
      this.$refs.form.getBackendValues().forEach((item) => {
        if (item.name === 'methodScript') {
          formData[item.name] = JSON.parse(item.value || '[]')
        } else {
          formData[item.name] = item.value
        }
      })
      return formData
    },
    loadEventsDefine() {
      if (this.eventsDefine.length === 0) {
        return eventHandlers.loadBackEnd().then((events) => {
          // 加载的事件定义存储至事件管理页面，避免新建事件、查看事件时重复加载事件定义
          this.$emit('updateEventsDefine', events)
        })
      }
      return Promise.resolve()
    },
    valueChange(value, fieldName) {
      // 触发时机
      if (fieldName === 'triggerMotor') {
        this.triggerMotor = value.target ? value.target.value : value
      }
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
.spin {
  width: 100%;
}
</style>
