<template>
  <div :class="$style.wrapper">
    <div :class="$style.caption">
      {{ label }}
      <div :class="$style.header">
        <a-space>
          <a-button :disabled="selectedRowKeys.length === 0" @click="remove(selectedRowKeys)">
            删除
          </a-button>
          <a-button type="primary" @click="add">
            新增
          </a-button>
        </a-space>
      </div>
    </div>
    <sd-table
      ref="table"
      size="middle"
      :columns="columns"
      sortable
      :data-source="dataSource"
      :row-key="(record, index) => index"
      :pagination="false"
      :row-selection="{
        selectedRowKeys: selectedRowKeys,
        onChange: (keys) => (selectedRowKeys = keys),
      }"
      :custom-row="
        (record, index) => {
          return {
            on: {
              click: () => {
                edit(index)
              },
            },
          }
        }
      "
      @update:data-source="(values) => $emit('change', JSON.stringify(values))"
    >
      <template slot="sd_methodType" slot-scope="text">
        {{ getEventDefineName(text) }}
      </template>
    </sd-table>
    <a-modal
      v-model="visible"
      :title="label || '详情'"
      destroy-on-close
      v-bind="{
        width: 800,
        bodyStyle: {
          minHeight: '380px',
        },
      }"
      :mask-closable="false"
      @ok="save"
      @cancel="visible = false"
    >
      <sdForm ref="form" :init-values="initValues">
        <template v-slot="{ model }">
          <table class="sd-form-table">
            <tr v-for="field in initValues" v-show="!field.sdHidden" :key="field.name">
              <sd-form-item-td :name="field.name">
                <!-- 触发条件 -->
                <sd-formula-compute
                  v-if="field.name === 'triggerPreconditionFormulaFD'"
                  v-model="model[field.name]"
                  :load-fields="loadFormulaFields"
                  value-string
                  data-type="boolean"
                  @update="
                    ($event) => {
                      $set(model, 'triggerPrecondition', $event)
                    }
                  "
                />
                <!-- 事件类型 -->
                <a-select
                  v-if="field.name === 'methodType'"
                  v-model="model.methodType"
                  :options="eventOptions"
                  @change="methodTypeChange"
                />
              </sd-form-item-td>
            </tr>
          </table>
        </template>
      </sdForm>
      <component
        :is="eventComponents[eventType]"
        v-if="!!eventType"
        ref="eventProps"
        :data-source="eventScript"
      />
    </a-modal>
  </div>
</template>

<script>
import ApplicationService from '@/application-manage/application-service'
import components from './_import-components/sd-events-child-table-import'

export default {
  name: 'SdEventsChildTable',
  components: {
    ...components,
    sdForm: () => import('@/common/components/sd-form'),
  },
  model: {
    prop: 'value',
    event: 'change',
  },
  props: {
    value: {
      type: String,
      default: '[]',
    },
    label: {
      type: String,
      default: '触发事件',
    },
    eventsDefine: {
      type: Array,
      default: () => [],
    },
    formId: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      selectedRowKeys: [],
      visible: false,
      editIndex: undefined,
      columns: [
        {
          title: '名称',
          dataIndex: 'methodName',
        },
        {
          title: '事件类型',
          dataIndex: 'methodType',
          scopedSlots: { customRender: 'sd_methodType' },
        },
      ],
      initValues: [
        {
          name: 'methodName',
          caption: '名称',
          dataType: 'string',
          required: true,
        },
        {
          name: 'methodType',
          caption: '事件类型',
          dataType: 'string',
          required: true,
        },
        {
          name: 'triggerPrecondition',
          caption: '触发条件(后端用)',
          dataType: 'string',
          sdHidden: true,
        },
        {
          name: 'triggerPreconditionFormulaFD',
          caption: '触发条件',
          dataType: 'string',
        },
      ],
      eventType: '',
      eventScript: {},
      formFields: {},
    }
  },
  computed: {
    dataSource() {
      return JSON.parse(this.value)
    },
    eventComponents() {
      const component = {}
      this.eventsDefine?.forEach((e) => {
        component[e.id] = e.module.default
      })
      return component
    },
    eventOptions() {
      return this.eventsDefine?.map((e) => ({ label: e.module.metaInfo?.name, value: e.id })) || []
    },
  },
  methods: {
    getEventDefineName(id) {
      return this.eventOptions.find((e) => e.value === id)?.label || id
    },
    add() {
      this.editIndex = undefined
      this.showDetailForm()
    },
    edit(key) {
      this.editIndex = key
      this.showDetailForm(this.dataSource[key])
    },
    showDetailForm(data) {
      if (data) {
        // 编辑
        this.initValues.forEach((f) => (f.value = data[f.name]))
        this.eventType = data.methodType
        this.eventScript = data
      } else {
        // 新建
        this.eventType = ''
        this.eventScript = {}
        // 清空字段值
        this.initValues.forEach((f) => (f.value = undefined))
      }
      this.visible = true
    },
    remove(keys) {
      const data = JSON.parse(this.value)
      // 用的序号作key，从大往小删，防止串了
      const removeKeys = keys.sort((a, b) => b - a)
      removeKeys.forEach((key) => {
        data.splice(key, 1)
      })
      this.selectedRowKeys = []
      this.$emit('change', JSON.stringify(data))
    },
    validate() {
      return Promise.all([
        this.$refs.form.validateFields?.() ?? true,
        this.$refs.eventProps.validate?.() ?? true,
      ]).then((flags) => {
        return flags.every((f) => f)
      })
    },
    save() {
      if (!this.visible) {
        // 判断visable为false时，modal没有是为了防止快速重复点击确定
        this.visible = false
        return
      }
      this.validate().then((flag) => {
        if (flag) {
          const value = { ...this.eventScript }
          this.$refs.form.getBackendValues().forEach((item) => {
            value[item.name] = item.value
          })
          const data = JSON.parse(this.value)
          if (isNaN(this.editIndex)) {
            // 新增
            data.push(value)
          } else {
            Object.assign(data[this.editIndex], value)
          }
          this.$emit('change', JSON.stringify(data))
          this.visible = false
        }
      })
    },
    methodTypeChange(value) {
      this.eventType = value
      const curRecord = !isNaN(this.editIndex) ? this.dataSource[this.editIndex] : {}
      this.eventScript = curRecord.methodType === this.eventType ? curRecord : {}
    },
    loadFormulaFields(dataTypes) {
      if (this.formFields[this.formId]) {
        return Promise.resolve(this.formFields[this.formId])
      }
      return ApplicationService.getOnlineFormById(this.formId).then((data) => {
        this.formFields[this.formId] = data.fields
        return data.fields
      })
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
.header {
  position: absolute;
  top: 0;
  right: 0;
  :global(.ant-btn-group > button:first-child) {
    padding: 0;
  }
  :global(.ant-btn > span) {
    pointer-events: auto;
  }
}
.caption {
  position: relative;
  width: 100%;
  min-height: 40px;
  margin: 3px 0;
  text-align: center;
}
.wrapper {
  :global(.ant-table-tbody) {
    .clickable-cell {
      color: $primary-color;
      cursor: pointer;
      &:hover {
        color: $primary-5;
      }
      &:active {
        color: $primary-7;
      }
    }
  }
}
</style>
