<template>
  <a-layout :class="$style.wrapper">
    <a-layout-sider v-if="!isPublished" theme="light" :width="300" :class="$style.left">
      <sd-component-library v-if="formProps" @itemDblClick="(v) => $refs.main.addComponent(v)" />
    </a-layout-sider>
    <sd-main
      v-if="formProps"
      ref="main"
      :class="{ [$style.invalid]: !isValid }"
      @selectionChange="selectionChange"
    >
      <sd-toolbar slot="header" />
    </sd-main>

    <a-layout v-else>
      <a-result v-if="hasError" status="warning" title="加载表单数据失败"> </a-result>
      <a-spin v-else :class="$style.spin" size="large">
        <div />
      </a-spin>
    </a-layout>

    <a-layout-sider theme="light" :width="300" :class="$style.right">
      <a-card title="字段属性" :class="$style.card">
        <sd-component-props v-if="selected && selected.attr" @validate="(val) => (isValid = val)" />
      </a-card>
    </a-layout-sider>
  </a-layout>
</template>

<script>
import flowForm from '@/webflow/sd-flow-form.vue'
import axios from '@/common/services/axios-instance'
import util from './util'
import components from './_import-components/sd-frame-import'

export default {
  name: 'SdFrame',
  metaInfo() {
    return {
      title: this.formProps?.tableTxt,
    }
  },
  components: {
    [flowForm.name]: flowForm,
    ...components,
  },
  model: {
    prop: 'value',
    event: 'change',
  },
  props: {
    id: {
      type: String,
      default: undefined,
    },
    value: {
      type: Object,
      default: undefined,
    },
  },
  data() {
    return {
      isValid: true,
      selectedID: undefined,
      visibleComponents: [],
      hiddenComponents: [],
      formProps: undefined,
      hasError: false,
    }
  },
  computed: {
    selected() {
      return this.componentInstances.find((item) => item.attrFD.id === this.selectedID)
    },
    isPublished() {
      return this.formProps?.isDbSynch
    },
    componentInstances() {
      return this.visibleComponents.concat(this.hiddenComponents)
    },
  },
  created() {
    let promise

    if (this.id) {
      // 编辑现有表单
      promise = this.loadForm().then((res) => {
        const formData = res.data
        if (formData.head.attrFD.theme) {
          // attrFD 有值，已经用设计器保存过
          return formData
        } else {
          // attrFD 没有值，用默认表单的相关信息填充进来
          return this.loadDefaultForm().then((defaultForm) => {
            formData.fields = defaultForm.fields
            formData.head.attrFD = defaultForm.head.attrFD
            return formData
          })
        }
      })
    } else if (this.value) {
      promise = Promise.resolve(this.value)
    } else {
      // 新建表单
      promise = this.loadDefaultForm()
    }
    promise.then(this.updateData)
  },
  provide: function() {
    return {
      designer: this,
    }
  },
  methods: {
    updateData(data) {
      // 替换内容前，先保存选中的name（因为id会新生成）
      const selectedName = this.selected?.name

      const hiddenComponents = []
      const visibleComponents = []
      data.fields
        .map((component) => util.createInstance(component, { formProps: data.head }))
        .forEach((field) => {
          if (field.attrFD.hidden) {
            hiddenComponents.push(field)
          } else {
            visibleComponents.push(field)
          }
        })
      this.hiddenComponents = hiddenComponents
      this.visibleComponents = visibleComponents
      this.formProps = data.head
      if (selectedName) {
        // 通过name找到之前选中的组件
        const selectedComponent = this.componentInstances.find((item) => item.name === selectedName)
        this.selectedID = selectedComponent.attrFD.id
      } else {
        this.selectedID = visibleComponents[0]?.attrFD.id
      }
    },
    selectionChange(val) {
      this.selectedID = val
    },
    loadForm() {
      return axios.get(`api/xcoa-mobile/v1/onlineform/getById/${this.id}/true`).catch((res) => {
        this.hasError = true
        return Promise.reject(res)
      })
    },
    loadDefaultForm() {
      const fields = [
        {
          caption: '标题',
          name: 'title',
          dataType: 'title',
          required: true,
          attrFD: {
            cid: 'sd-text',
            columns: 2,
          },
        },
      ]
      return Promise.resolve({
        head: {
          tableTxt: '新表单',
          tableName: 'form_' + Date.now(),
          tableType: 1, // 单表
          formType: 1, // 流程表单
          attrFD: {
            columns: 2,
            theme: 'sd-default',
          },
        },
        fields,
      })
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
.wrapper {
  height: 100%;
  .left {
    border-right: 1px solid $border-color-base;
  }
  .right {
    border-left: 1px solid $border-color-base;
  }

  .card {
    display: flex;
    flex-direction: column;
    height: 100%;
    :global(.ant-card-head-title) {
      padding: 10px 0;
      text-align: center;
    }
    :global(.ant-card-body) {
      overflow: auto;
    }
  }
  .invalid::after {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    cursor: not-allowed;
    content: '';
    background-color: $white;
    opacity: 0.5;
  }
  .spin {
    :global(.ant-spin) {
      height: 100vh;
      max-height: none;
    }
  }
}
</style>
