<template>
  <sd-form 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"
            :label="field.dataType === 'collection' ? null : undefined"
            :colspan="field.dataType === 'collection' ? 2 : 1"
            @change="(value) => valueChange(value, field.name)"
          >
            <!-- 来源表单 -->
            <a-select
              v-if="field.name === 'srcForm'"
              v-model="model[field.name]"
              option-label-prop="label"
              @change="(value) => valueChange(value, field.name)"
            >
              <a-select-opt-group
                v-for="group in srcFormOptions"
                :key="group.key"
                :label="group.label"
              >
                <a-select-option
                  v-for="opt in group.options"
                  :key="opt.value"
                  :value="opt.value"
                  :label="opt.prefix + opt.label"
                >
                  {{ opt.label }}
                </a-select-option>
              </a-select-opt-group>
            </a-select>
            <!-- 目标表单 -->
            <sd-list-picker
              v-if="field.name === 'associateFormSrc'"
              v-model="model[field.name]"
              single
              :load-list-data="loadOnlineFormListPickerData"
              @change="(value) => valueChange(value, 'associateForm')"
            />
            <!-- 关联条件 -->
            <sd-associate-conditions
              v-if="field.name === 'associateConditions'"
              v-model="dataSource.associateConditions"
              :dest-form-id="dataSource.associateForm"
              :src-form-id="SdEventsManage.formId"
              :src-child-table-name="srcChildTableName"
              :disabled-types="['attachment', 'OpinionView']"
              :dest-disabled-types="['collection', 'attachment', 'OpinionView']"
              multiple
              @change="(value) => valueChange(value, field.name)"
            />
            <!-- 字段赋值 -->
            <template
              v-if="field.name === 'methodItems'"
              v-slot:input-form="{ model: subModel, fields: subFields }"
            >
              <table class="sd-form-table">
                <tr>
                  <sd-form-item-td name="destColumnSrc">
                    <sd-field-picker
                      v-model="subModel.destColumnSrc"
                      :form-id="dataSource.associateForm"
                      :disabled-keys="getConfiguredFields(subFields)"
                      type="number"
                      @change="
                        (v) => {
                          subModel.destColumn = v?.[0]?.id
                        }
                      "
                    />
                  </sd-form-item-td>
                </tr>
                <tr>
                  <sd-form-item-td name="updateType" />
                </tr>
                <tr>
                  <sd-form-item-td name="value">
                    <!-- 公式 -->
                    <sd-formula-compute
                      v-model="subModel.formulaFD"
                      :load-fields="loadFormulaFields"
                      :data-type="subModel.destColumnSrc?.[0]?.type || undefined"
                      value-string
                      @update="
                        ($event) => {
                          $set(subModel, 'value', $event)
                        }
                      "
                    />
                  </sd-form-item-td>
                </tr>
              </table>
            </template>
            <!-- 子表：字段显示 -->
            <template v-if="field.name === 'methodItems'" v-slot:input-destColumnSrc="{ text }">
              {{ JSON.parse(text || '[{}]')[0].name || '' }}
            </template>
            <template v-if="field.name === 'methodItems'" v-slot:input-updateType="{ text }">
              {{ getDisplayValue(text) }}
            </template>
            <template v-if="field.name === 'methodItems'" v-slot:input-value="{ text, record }">
              <sd-value-display v-bind="{ text, record: { ...record, opType: 'formula' } }" />
            </template>
          </sd-form-item-td>
        </tr>
      </table>
    </template>
  </sd-form>
</template>

<script>
import ApplicationService from '@/application-manage/application-service'
import sdValueDisplay from './child-table/sd-value-display.vue'
import components from './_import-components/sd-numerical-update-import'

export const metaInfo = {
  name: '数值变更',
  order: 500,
  // 标签：对事件处理器进行描述
  tags: ['updateData'],
}

const updateTypeOptions = [
  { label: '自增', value: 'self-add' },
  { label: '自减', value: 'self-minus' },
]

export default {
  name: 'SdNumericalUpdate',
  components: {
    ...components,
    sdValueDisplay,
  },
  data() {
    return {
      initValues: [
        {
          name: 'srcForm',
          caption: '当前表单',
          dataType: 'string',
          attr: {},
          attrFD: {
            popoverDescription: true,
            description: '<p>事件执行时提供数据的表</p>',
          },
        },
        {
          name: 'associateForm',
          caption: '目标表单(id)',
          dataType: 'string',
          sdHidden: true,
          attr: {},
        },
        {
          name: 'associateFormSrc',
          caption: '目标表单',
          dataType: 'string',
          required: true,
          attr: {},
        },
        {
          name: 'associateConditions',
          caption: '关联条件',
          dataType: 'string',
          required: true,
          attr: {},
        },
        {
          name: 'methodItems',
          caption: '字段赋值',
          dataType: 'collection',
          attr: {
            dync: [
              {
                name: 'destColumn',
                caption: '表单字段(id)',
                dataType: 'string',
                sdHidden: true,
                attr: {},
              },
              {
                name: 'destColumnSrc',
                caption: '表单字段',
                dataType: 'string',
                required: true,
                attr: {},
              },
              {
                name: 'updateType',
                caption: '变更方式',
                dataType: 'selectlist',
                required: true,
                attr: {
                  selectListItem: updateTypeOptions,
                },
              },
              {
                name: 'value',
                caption: '值',
                dataType: 'string',
                attr: {},
              },
              {
                name: 'formulaFD',
                caption: '公式',
                dataType: 'string',
                sdHidden: true,
                attr: {},
              },
            ],
          },
        },
      ],
      formFieldsMap: {},
      srcFormOptions: [],
      mainTable: '__mainTable__',
    }
  },
  computed: {
    srcChildTableName() {
      return this.dataSource.srcForm
    },
  },
  created() {
    const isEdit = Object.keys(this.dataSource).length > 0
    // 编辑时
    if (isEdit) {
      this.initValues.forEach((f) => {
        if (f.name === 'srcForm') {
          f.value = this.dataSource[f.name] ?? this.mainTable
        } else {
          const value = this.dataSource[f.name]
          f.value = value && typeof value === 'object' ? JSON.stringify(value) : value
        }
      })
    } else {
      // 新建时，来源表默认为主表
      this.initValues.find((f) => f.name === 'srcForm').value = this.mainTable
    }
    // 获取当前表单的表
    ApplicationService.getOnlineFormById(this.SdEventsManage.formId).then((data) => {
      this.formFieldsMap[this.SdEventsManage.formId] = data.fields
      const optionGroup = [
        {
          label: '主表',
          key: 'main',
          options: [{ label: data.head.tableTxt, value: this.mainTable, prefix: '' }],
        },
      ]
      optionGroup.push({
        label: '子表',
        key: 'sub',
        options: data.fields
          .filter((f) => f.dataType === 'collection')
          .map((f) => ({ label: f.caption, value: f.name, prefix: '[子表]' })),
      })
      // 主表+子表
      this.srcFormOptions = optionGroup
    })
  },
  methods: {
    validate() {
      return this.$refs.form.validateFields()
    },
    getConfiguredFields(fields) {
      return (
        this.$refs.form
          .getFieldValue('methodItems')
          ?.map((v) => v.destColumn)
          .concat(['id'])
          .filter((i) => i !== fields.destColumn.value) || []
      )
    },
    loadOnlineFormListPickerData() {
      return ApplicationService.getOnlFormListData(this.SdEventsManage.appId)
    },
    loadFormulaFields() {
      return new Promise((resolve) => {
        // 来源表指定为子表，返回子表字段，否则返回主表字段
        if (this.srcChildTableName) {
          resolve(
            this.formFieldsMap[this.SdEventsManage.formId].find(
              (f) => f.name === this.srcChildTableName
            )?.attr.dync || []
          )
        } else {
          resolve(
            this.formFieldsMap[this.SdEventsManage.formId]?.filter(
              (f) => f.dataType !== 'OpinionView'
            )
          )
        }
      })
    },
    getDisplayValue(text) {
      return updateTypeOptions.find((_) => _.value === text)?.label || text
    },
    valueChange(value, field) {
      if (field === 'associateForm') {
        const vid = value[0]?.id
        this.$refs.form.setFieldValue(field, vid)
        this.dataSource[field] = vid
        this.dataSource[field + 'Src'] = value
      } else if (field === 'associateConditions') {
        const v = value?.filter((c) => c.destColumn?.[0] && c.srcColumn?.[0])
        this.$refs.form.setFieldValue('associateConditions', v?.length > 0 ? v : undefined)
      } else if (field === 'srcForm') {
        // 选择的不是主表，则记录来源表
        if (value !== this.mainTable) {
          this.$set(this.dataSource, field, value)
        } else {
          // 选择的是主表，则删除记录中的来源表信息（默认就是主表，不用再传）
          this.$delete(this.dataSource, field)
        }
        // 清空关联条件
        if (this.dataSource.associateConditions?.length > 0) {
          this.$delete(this.dataSource, 'associateConditions')
          this.$refs.form.setFieldValue('associateConditions', undefined)
        }
        // 清空字段赋值
        if (this.dataSource.methodItems?.length > 0) {
          this.$delete(this.dataSource, 'methodItems')
          this.$refs.form.setFieldValue('methodItems', undefined)
        }
      } else {
        this.dataSource[field] = value
      }
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
</style>
