<template>
  <sd-form ref="form" :init-values="fields">
    <template v-slot="{ model }">
      <table class="sd-form-table">
        <tr v-for="field in fields" 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, model)"
          >
            <!-- 目标表单 -->
            <sd-list-picker
              v-if="field.name === 'associateForm$Src'"
              v-model="model[field.name]"
              single
              :load-list-data="loadOnlineFormListPickerData"
              @change="(value) => valueChange(value, 'associateForm')"
            />
            <!-- 关联条件 -->
            <sd-associate-conditions
              v-if="field.name === 'associateCondition'"
              v-model="associateConditions"
              :dest-form-id="dataSource.associateForm"
              :src-form-id="SdEventsManage.formId"
            />
            <!-- 写入、写出子表 -->
            <template
              v-if="['dataIn', 'dataOut'].includes(field.name)"
              v-slot:input-form="{ model: subModel, fields: subFields }"
            >
              <table class="sd-form-table">
                <tr>
                  <sd-form-item-td name="destColumn$Src">
                    <sd-field-picker
                      v-model="subModel.destColumn$Src"
                      :form-id="
                        field.name === 'dataIn' ? SdEventsManage.formId : dataSource.associateForm
                      "
                      :disabled-keys="
                        [...getSubTableFields(field.name), 'id'].filter(
                          (i) => i !== subFields.destColumn.value
                        )
                      "
                      :disabled-types="['OpinionView']"
                      :type="subModel.srcColumn?.[0]?.type"
                      @change="
                        (v) => {
                          subModel.destColumn = v?.[0]?.id
                          if (field.name === 'dataOut') {
                            // 还原 变更模式和去除重复的设置
                            subModel.mode = subFields.mode.attr.defaultValue
                            subModel.validateRepeat = subFields.validateRepeat.attr.defaultValue
                          }
                        }
                      "
                    />
                  </sd-form-item-td>
                </tr>
                <tr>
                  <sd-form-item-td
                    name="opType"
                    @change="
                      () => {
                        subModel.value = undefined
                        subModel.srcColumn = undefined
                        subModel.formulaFD = undefined
                      }
                    "
                  />
                </tr>
                <tr>
                  <sd-form-item-td name="value">
                    <!-- 公式 -->
                    <sd-formula-compute
                      v-if="subModel.opType === 'formula'"
                      v-model="subModel.formulaFD"
                      :load-fields="
                        () => loadFormulaFields(field.name === 'dataIn' ? 'target' : '')
                      "
                      :data-type="subModel.destColumn$Src?.[0]?.type || undefined"
                      :constants="constants"
                      value-string
                      @update="
                        ($event) => {
                          $set(subModel, 'value', $event)
                        }
                      "
                    />
                  </sd-form-item-td>
                </tr>
                <tr>
                  <!-- 赋表单值 -->
                  <sd-form-item-td name="srcColumn" label="值">
                    <sd-field-picker
                      v-model="subModel.srcColumn"
                      :form-id="
                        field.name === 'dataIn' ? dataSource.associateForm : SdEventsManage.formId
                      "
                      :type="subModel.destColumn$Src?.[0]?.type"
                      :disabled-types="['OpinionView']"
                      @change="
                        (v) => {
                          subModel.value = v?.[0]?.id
                        }
                      "
                    />
                  </sd-form-item-td>
                </tr>
                <tr>
                  <!-- 数据更新模式显示：写出数据 且 目标表单字段是高级字段（人员或部门）或 子表 -->
                  <sd-form-item-td
                    v-if="
                      field.name === 'dataOut' &&
                        (['user', 'group'].includes(subModel.destColumn$Src?.[0]?.type) ||
                          subModel.destColumn?.indexOf('.') > -1)
                    "
                    name="mode"
                  />
                </tr>
                <tr>
                  <sd-form-item-td v-if="field.name === 'dataOut'" name="validateRepeat" />
                </tr>
              </table>
            </template>
            <!-- 写入、写出子表：字段显示 -->
            <template
              v-if="['dataIn', 'dataOut'].includes(field.name)"
              v-slot:input-destColumn$Src="scope"
            >
              <sd-value-display v-bind="scope" type="destColumn" />
            </template>
            <template v-if="field.name === 'dataOut'" v-slot:input-validateRepeat="scope">
              <sd-value-display v-bind="scope" type="repeat" />
            </template>
            <template v-if="field.name === 'dataOut'" v-slot:input-mode="scope">
              <sd-value-display v-bind="scope" type="mode" />
            </template>
            <template v-if="['dataIn', 'dataOut'].includes(field.name)" v-slot:input-value="scope">
              <sd-value-display v-bind="scope" />
            </template>
          </sd-form-item-td>
        </tr>
      </table>
    </template>
  </sd-form>
</template>

<script>
import { message } from '@/common/one-ui'
import ApplicationService from '@/application-manage/application-service'
import sdValueDisplay from './child-table/sd-value-display.vue'
import components from './_import-components/sd-data-copy-import'

export const metaInfo = {
  name: '更新',
  order: 200,
}

export default {
  name: 'SdDataCopy',
  components: {
    ...components,
    sdValueDisplay,
  },
  data() {
    return {
      fields: [
        {
          name: 'associateForm',
          caption: '目标表单(id)',
          dataType: 'string',
          sdHidden: true,
          attr: {},
        },
        {
          name: 'associateForm$Src',
          caption: '目标表单',
          dataType: 'string',
          required: true,
          attr: {},
        },
        {
          name: 'associateCondition',
          caption: '关联条件',
          dataType: 'string',
          attr: {},
        },
        {
          name: 'dataDirection',
          caption: '数据流向',
          dataType: 'selectlist',
          required: true,
          attr: {
            multiple: 'false',
            selectListItem: [
              { label: '写入', value: '1' },
              { label: '写出', value: '2' },
            ],
          },
          attrFD: {
            popoverDescription: true,
            description:
              '<div>写入：目标表单数据传入至当前表单</div><div>写出：当前表单数据传出至目标表单</div>',
          },
        },
        {
          name: 'dataIn',
          caption: '写入数据',
          dataType: 'collection',
          attr: {
            displayExpr: '#bean.dataDirection == "1"',
            dync: [
              {
                name: 'destColumn',
                caption: '当前表单(字段id)',
                dataType: 'string',
                sdHidden: true,
                attr: {},
              },
              {
                name: 'destColumn$Src',
                caption: '当前表单(字段)',
                dataType: 'string',
                required: true,
                attr: {},
              },
              {
                name: 'opType',
                caption: '赋值方式',
                dataType: 'selectlist',
                attr: {
                  defaultValue: 'direct',
                  selectListItem: [
                    { label: '赋表单值', value: 'direct' },
                    { label: '手动输入', value: 'manual' },
                    { label: '公式', value: 'formula' },
                  ],
                },
              },
              {
                name: 'value',
                caption: '值',
                dataType: 'string',
                attr: {
                  displayExpr: '#bean.opType != "direct"',
                },
              },
              {
                name: 'srcColumn',
                caption: '目标表单(字段)',
                dataType: 'string',
                sdHidden: true,
                attr: {
                  displayExpr: '#bean.opType == "direct"',
                },
              },
              {
                name: 'formulaFD',
                caption: '公式',
                dataType: 'string',
                sdHidden: true,
                attr: {},
              },
            ],
          },
        },
        {
          name: 'dataOut',
          caption: '写出数据',
          dataType: 'collection',
          attr: {
            displayExpr: '#bean.dataDirection == "2"',
            dync: [
              {
                name: 'destColumn',
                caption: '目标表单(字段id)',
                dataType: 'string',
                sdHidden: true,
                attr: {},
              },
              {
                name: 'destColumn$Src',
                caption: '目标表单(字段)',
                dataType: 'string',
                required: true,
                attr: {},
              },
              {
                name: 'opType',
                caption: '赋值方式',
                dataType: 'selectlist',
                attr: {
                  defaultValue: 'direct',
                  selectListItem: [
                    { label: '赋表单值', value: 'direct' },
                    { label: '手动输入', value: 'manual' },
                    { label: '公式', value: 'formula' },
                  ],
                },
              },
              {
                name: 'value',
                caption: '值',
                dataType: 'string',
                attr: {
                  displayExpr: '#bean.opType != "direct"',
                },
              },
              {
                name: 'srcColumn',
                caption: '当前表单(字段)',
                dataType: 'string',
                sdHidden: true,
                attr: {
                  displayExpr: '#bean.opType == "direct"',
                },
              },
              {
                name: 'formulaFD',
                caption: '公式',
                dataType: 'string',
                sdHidden: true,
                attr: {},
              },
              {
                name: 'mode',
                caption: '数据变更模式',
                dataType: 'string',
                attr: {
                  defaultValue: 'update',
                  selectListItem: [
                    { label: '变更', value: 'update' },
                    { label: '新增', value: 'insert' },
                  ],
                },
              },
              {
                name: 'validateRepeat',
                caption: '去除重复',
                dataType: 'selectlist',
                attr: {
                  defaultValue: '0',
                  displayExpr: '#bean.mode == "insert"',
                  selectListItem: [
                    { label: '是', value: '1' },
                    { label: '否', value: '0' },
                  ],
                },
              },
            ],
          },
        },
      ],
      formulaFieldsMap: [],
      constants: [],
    }
  },
  computed: {
    associateConditions: {
      get() {
        if (this.dataSource.associateFormKey$Src) {
          return [
            {
              destColumn: this.dataSource.associateFormKey$Src,
              op: 'eq',
              srcColumn: this.dataSource.keyColumn$Src,
            },
          ]
        }
        return undefined
      },
      set(value) {
        const dest = value?.[0]?.destColumn
        const src = value?.[0]?.srcColumn
        this.$set(this.dataSource, 'associateFormKey', dest?.[0]?.id)
        this.$set(this.dataSource, 'associateFormKey$Src', dest)
        this.$set(this.dataSource, 'keyColumn', src?.[0]?.id)
        this.$set(this.dataSource, 'keyColumn$Src', src)
      },
    },
  },
  created() {
    // 编辑时
    if (Object.keys(this.dataSource).length > 0) {
      this.fields.forEach((f) => {
        // 目标表单
        if (f.name === 'dataIn') {
          if (this.dataSource.dataDirection === '1') {
            f.value = JSON.stringify(this.dataSource.methodItems)
          }
        } else if (f.name === 'dataOut') {
          if (this.dataSource.dataDirection === '2') {
            f.value = JSON.stringify(this.dataSource.methodItems)
          }
        } else {
          const value = this.dataSource[f.name]
          f.value = value && typeof value === 'object' ? JSON.stringify(value) : value
        }
      })
      this.updateConstants()
    } else {
      // 新建：目标表单的主键默认值为id
      const OID = [{ id: 'id', name: '文档唯一ID(系统)', type: 'string' }]
      this.$set(this.dataSource, 'associateFormKey', OID[0].id)
      this.$set(this.dataSource, 'associateFormKey$Src', OID)
    }
  },
  methods: {
    validate() {
      if (!this.dataSource.keyColumn || !this.dataSource.associateFormKey) {
        message.error('关联条件不能为空')
        return Promise.resolve(false)
      }
      return this.$refs.form.validateFields()
    },
    getSubTableFields(fieldName) {
      return this.$refs.form.getFieldValue(fieldName)?.map((v) => v.destColumn) || []
    },
    loadFormulaFields(type) {
      const formId =
        type === 'target'
          ? this.$refs.form.getFieldValue('associateForm')
          : this.SdEventsManage.formId
      if (!this.formulaFieldsMap[formId]) {
        return ApplicationService.getFormulaFields(formId).then((fields) => {
          this.formulaFieldsMap[formId] = fields
          return fields
        })
      }
      return Promise.resolve(this.formulaFieldsMap[formId])
    },
    loadOnlineFormListPickerData() {
      return ApplicationService.getOnlFormListData(this.SdEventsManage.appId)
    },
    valueChange(value, field, model) {
      if (['associateForm'].includes(field)) {
        const vid = value[0]?.id
        this.$refs.form.setFieldValue(field, vid)
        this.$set(this.dataSource, field, vid)
        this.$set(this.dataSource, field + '$Src', value)
        this.updateConstants()
      } else if (field === 'dataDirection') {
        this.dataSource[field] = value.target.value
        this.dataSource.methodItems = value === '1' ? model.dataIn : model.dataOut
        this.updateConstants()
      } else if (['dataIn', 'dataOut'].includes(field)) {
        this.dataSource.methodItems = value
      }
    },
    updateConstants() {
      const formId =
        this.dataSource.dataDirection === '1'
          ? this.SdEventsManage.formId
          : this.dataSource.associateForm
      ApplicationService.getFormConstants(formId).then((consts) => {
        this.constants = consts
      })
    },
  },
}
</script>

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