<template>
  <a-modal
    v-if="visible"
    v-model="visible"
    destroy-on-close
    width="1000px"
    title="关联配置"
    :footer="null"
  >
    <sd-data-table-ex
      ref="table"
      form-id="weFormDataAssociation"
      page-id="app/formdataassociation/weFormDataAssociation"
      :columns="columns"
      :actions="actions"
      show-selection
      :filter-expressions="[
        {
          dataType: 'str',
          name: 'targetId',
          op: 'like',
          stringValue: '%' + toForm[0].id + '%',
        },
      ]"
      @formBtnClick="formBtnClick"
      @detailModalShow="detailModalShow"
    >
      <template v-slot:form="{ model }">
        <formWatcher :model="model" @formLoad="formLoad" />
        <sd-form-item name="name"> </sd-form-item>
        <sd-form-item name="toForm">
          <sd-form-picker ref="toForm" v-model="model.toForm" read-only />
        </sd-form-item>
        <sd-form-item name="fromForm" required>
          <sd-form-picker
            :value="model.fromForm"
            :disabled-keys="[toForm[0].id]"
            :app-id="$route.query.appId"
            @change="(value) => change(value, model)"
          />
        </sd-form-item>
        <sd-form-item v-show="sdGet(model, 'fromForm?.length')" name="fromFormList">
          <sd-list-picker
            :load-list-data="() => loadFormViewListData(model.fromForm)"
            single
            :value="model.fromFormList"
            @change="
              (value) => {
                if (!value || !value.length) {
                  model.frontData = '{}'
                }
                model.fromFormList = value
              }
            "
          />
          <sd-list-variable-config
            :value="JSON.parse(model.frontData || '{}').customFields"
            :activated="activated"
            :module-id="fromModuleId"
            :form-list-id="
              sdGet(model, 'fromFormList?.length') ? model.fromFormList[0].id : undefined
            "
            :formula-fields="formulaFields"
            @input="
              (customFields) => {
                model.frontData = JSON.stringify({
                  ...JSON.parse(model.frontData || '{}'),
                  customFields,
                })
              }
            "
          />
        </sd-form-item>
        <a-form-item v-if="sdGet(model, 'fromForm?.length')" name="fieldsMap" label="关联">
          <a-button
            type="link"
            icon="plus"
            @click="fieldsMap.push({ toField: [], fromField: [] })"
          />
          <a-row v-for="(item, index) in fieldsMap" :key="index" :gutter="[4, 8]">
            <a-col :span="4">
              <a-checkbox
                v-model="item.selector"
                :disabled="!sdGet(item, 'toField?.length')"
                @change="() => setSelector(item)"
              >
                选择器
              </a-checkbox>
            </a-col>
            <a-col :span="8">
              <sd-field-picker
                v-model="item.toField"
                :form-id="model.toForm[0].id"
                :disabled-keys="
                  [...otherFieldsMap, ...fieldsMap]
                    .map((i) => i.toField[0] && i.toField[0].id)
                    .filter((i) => i !== (item.toField[0] && item.toField[0].id))
                "
                :disabled-types="['OpinionView']"
                :type="item.fromField[0] && item.fromField[0].type"
                placeholder="目标表单字段"
              />
            </a-col>
            <a-col :span="1"><a-icon type="sd-double-left"/></a-col>
            <a-col :span="8">
              <sd-field-picker
                v-model="item.fromField"
                :form-id="model.fromForm[0].id"
                :type="item.toField[0] && item.toField[0].type"
                :disabled-types="['OpinionView']"
                placeholder="来源表单字段"
              />
            </a-col>
            <a-col :span="2">
              <a-icon type="delete" @click="() => fieldsMap.splice(index, 1)" />
            </a-col>
          </a-row>
        </a-form-item>
      </template>
    </sd-data-table-ex>
  </a-modal>
</template>

<script>
import { message } from '@/common/one-ui'
import TableActionTypes from '@/common/services/table-action-types'
import axios from '@/common/services/axios-instance'
import sdListVariableConfig from '@/form-designer/component-library/components/sd-list-variable-config.vue'
import components from './_import-components/sd-form-relation-import'
export default {
  name: 'SdFormRelation',
  metaInfo: {
    title: 'SdFormRelation',
  },
  components: {
    formWatcher: {
      mounted() {
        this.$emit('formLoad')
      },
      render() {
        return ''
      },
    },
    'sd-list-variable-config': sdListVariableConfig,
    ...components,
  },
  data() {
    return {
      actions: [
        {
          label: '新建',
          id: 'new',
          type: TableActionTypes.ex.create, // 新建按钮，不需要回调，自动处理
        },
        {
          label: '删除',
          id: 'delete',
          type: TableActionTypes.ex.delete, // 删除按钮，不需要回调，会自动处理
        },
      ],
      columns: [
        {
          title: '关系名称',
          dataIndex: 'name',
          sdClickable: true,
        },
        {
          title: '目标表单',
          dataIndex: 'toForm',
          sdClickable: true,
          customRender: (text, record, index) => {
            return JSON.parse(text)[0].name
          },
        },
        {
          title: '来源表单',
          dataIndex: 'fromForm',
          customRender: (text, record, index) => {
            return JSON.parse(text)[0].name
          },
        },
      ],
      visible: false,
      toForm: undefined,
      fieldsMap: undefined,
      otherFieldsMap: [],
      activated: false,
      formulaFields: [],
      fromModuleId: undefined,
    }
  },
  methods: {
    show(item) {
      this.toForm = [
        {
          id: item.formId,
          name: item.name,
        },
      ]
      this.visible = true
    },
    formBtnClick(evt, btn, { form, recordId }) {
      switch (btn.buttonId) {
        case 'save':
          evt.waitUntil(
            new Promise((resolve) => {
              if (this.fieldsMap.length === 0) {
                message.error('关联关系不能为空')
                evt.preventDefault()
                resolve()
              }
              if (this.fieldsMap.some((item) => !item.toField.length || !item.fromField.length)) {
                message.error('关联关系不能为空')
                evt.preventDefault()
                resolve()
              }
              let formCates = [] // 表单分类
              this.fieldsMap.forEach((item) => {
                formCates.push(('.' + item.toField[0].id).split('.').slice(-2)[0]) // 找到字段的子表前缀
              })
              formCates = [...new Set(formCates)]
              if (this.fieldsMap.filter((item) => item.selector).length !== formCates.length) {
                message.error('请给主表或子表字段各设置一个选择器')
                evt.preventDefault()
                resolve()
              }
              form.setFieldValue('fieldsMap', JSON.stringify(this.fieldsMap))
              resolve()
            })
          )
          break
        default:
          break
      }
    },
    formLoad() {
      this.activated = false
      const form = this.$refs.table.getDetailModal()
      form.setFieldValue('toForm', this.toForm)
      this.fieldsMap = JSON.parse(form.getFieldValue('fieldsMap') || '[]')
      this.getFormulaFields().then(() => {
        this.activated = true
      })
      if (form.getFieldValue('fromFrom'))
        axios
          .get(
            'api/framework/v1/we-app-module/get-module-id?formId=' +
              form.getFieldValue('fromFrom')[0].id
          )
          .then((res) => {
            this.fromModuleId = res.data.moduleId
          })
    },
    detailModalShow(id) {
      // 找到其他配置的映射字段，不能选，同一个字段只能在一条记录出现
      axios
        .post('api/framework/v1/page/businessList', {
          columns: 'toForm,fromForm,fieldsMap',
          maxResults: -1,
          expressions: [
            {
              dataType: 'str',
              name: 'targetId',
              op: 'like',
              stringValue: `%${this.toForm[0].id}%`,
            },
            {
              dataType: 'str',
              name: 'id',
              op: 'ne',
              stringValue: `${id || -1}`,
            },
          ],
          formId: 'weFormDataAssociation',
        })
        .then((res) => {
          const otherfieldsMap = res.data.data.map((item) => {
            return JSON.parse(item.fieldsMap)
          })
          this.otherFieldsMap = [].concat(...otherfieldsMap)
        })
    },
    setSelector(item) {
      const childname = ('.' + item.toField[0].id).split('.').slice(-2)[0] // 找到字段的子表前缀
      this.fieldsMap.forEach((i) => {
        if (childname && i.toField[0]?.id?.startsWith(childname)) {
          // 一个子表只能设置一个选择器
          i.selector = false
        }
        if (!childname && !i.toField[0]?.id?.includes('.')) {
          // 主表只能设置一个选择器
          i.selector = false
        }
      })
      item.selector = true
      this.fieldsMap = [...this.fieldsMap]
    },
    change(value, model) {
      this.fieldsMap = []
      model.fromForm = value
      model.fromFormList = undefined
      if (!value || !value.length) {
        model.frontData = '{}'
      }
      this.getFormulaFields()
    },
    loadFormViewListData(fromForm) {
      const formId = fromForm[0].id
      return axios
        .get('api/framework/v1/we-app-module/get-module-id?formId=' + formId)
        .then((res) => {
          this.fromModuleId = res.data?.moduleId
          return axios({
            url: 'api/framework/v1/page/businessList',
            method: 'post',
            data: {
              startPosition: 0,
              maxResults: -1,
              expressions: [
                {
                  dataType: 'str',
                  name: 'appModuleId',
                  op: 'eq',
                  stringValue: this.fromModuleId,
                },
              ],
              formId: 'weAppFormList',
              orderBy: 'sortNumber asc,id asc',
              columns: 'id,name',
            },
          }).then((res) => {
            return res.data.data.map((item) => ({ id: item.id, name: item.name }))
          })
        })
    },
    getFormulaFields() {
      return axios
        .get(`api/framework/v1/onlineform/getById/${this.toForm[0].id}/true`)
        .then((res) => res.data.fields)
        .then((fields) => {
          // 把子表字段拉平到一层给自定义变量公式，让当前子表和主表的数据都能选
          const childFields = fields
            .filter((item) => item.dataType === 'collection')
            .map((item) => {
              const dync = JSON.parse(JSON.stringify(item.attr.dync))
              dync.forEach((i) => {
                // 主表字段和子表字段如果是中间是点会当成数组对待处理，这里就是把子表的字段和主表放一起作为普通字段参与计算
                i.name = item.name + '_' + i.name
                i.caption = `${item.caption}.${i.caption}`
              })
              return dync
            })
          this.formulaFields = fields
            .concat(...childFields)
            .filter((item) => item.dataType !== 'collection')
        })
    },
  },
}
</script>

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