<template>
  <div>
    <span v-if="formProps.formType === 1">
      <a-button icon="mobile" type="link" @click="previewMobile">移动端预览</a-button>
      <a-button icon="desktop" type="link" @click="preview">PC端预览</a-button>
      <a-button icon="profile" type="link" @click="editFormProps">表单属性</a-button>
      <a-button icon="save" type="link" :loading="saving" @click="save">保存</a-button>
    </span>
    <span v-else>
      <a-button
        icon="save"
        type="link"
        :loading="saving"
        @click="designer.$emit('change', getSaveData())"
      >
        确定
      </a-button>
    </span>

    <a-modal
      v-model="showPreview"
      :footer="null"
      destroy-on-close
      :dialog-class="$style.preview"
      width="100%"
      :closable="false"
    >
      <sd-render :fields="fields" :form-props="formProps" @close="showPreview = false" />
    </a-modal>
    <a-modal
      v-model="showPreviewMobile"
      :footer="null"
      destroy-on-close
      centered
      :dialog-class="$style.previewMobile"
    >
      <sd-phone-frame>
        <sd-mobile-render :fields="fields" :form-props="formProps" />
      </sd-phone-frame>
    </a-modal>
    <a-modal
      v-model="showFormProps"
      :footer="null"
      title="表单属性"
      width="800px"
      destroy-on-close
      @cancel="hideFormProps"
    >
      <a-form-model
        :model="formProps"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 18 }"
        @validate="onValidate"
      >
        <a-form-model-item label="标题" prop="tableTxt" :rules="[{ required: true }]">
          <a-input v-model.trim="formProps.tableTxt" />
        </a-form-model-item>
        <a-form-model-item
          label="英文ID"
          prop="tableName"
          :rules="[{ required: true }, { validator: checkDbName }]"
        >
          <a-input v-model.trim="formProps.tableName" :read-only="isPublished" />
        </a-form-model-item>
        <a-form-model-item
          label="布局总列数"
          extra="表示一行可以放几个字段（字段的label和输入框加起来算一列）"
        >
          <a-input-number v-model="formProps.attrFD.columns" />
        </a-form-model-item>
        <a-form-model-item label="样式">
          <a-radio-group v-model="formProps.attrFD.theme">
            <a-radio-button v-for="theme in themes" :key="theme.id" :value="theme.id">
              {{ theme.name }}
            </a-radio-button>
          </a-radio-group>
        </a-form-model-item>
        <a-form-model-item label="填写说明" :wrapper-col="{ span: 24 }">
          <sd-quill-editor
            v-model="formProps.attrFD.description"
            :options="{ placeholder: '可在表单中添加备注说明，帮助用户理解业务' }"
          />
        </a-form-model-item>
      </a-form-model>
    </a-modal>
  </div>
</template>

<script>
import axios from '@/common/services/axios-instance'
import { message } from 'ant-design-vue'
import crossWindowWatcher from '@/common/services/cross-window-watcher'
import util from './util'
import components from './_import-components/sd-toolbar-import'

export default {
  name: 'SdToolbar',
  components,
  mixins: [util.mixin],
  data() {
    return {
      showPreview: false,
      showPreviewMobile: false,
      showFormProps: false,
      fields: undefined,
      themes: util.getThemes(),
      saving: false,
      validateStatus: {},
      fullPath: this.$route.fullPath, // 保存好最初的url，保存后可能会变化
      dataSaved: undefined, // 已经保存的数据，用于检查是否有修改
    }
  },
  computed: {
    isValid() {
      for (const key in this.validateStatus) {
        if (!this.validateStatus[key]) return false
      }
      return true
    },
  },
  created() {
    this.updateDataSaved()
    window.addEventListener('unload', this.onPageUnload)
    window.addEventListener('beforeunload', this.checkUnsavedData)
  },
  destroyed() {
    window.removeEventListener('unload', this.onPageUnload)
    window.removeEventListener('beforeunload', this.checkUnsavedData)
  },
  methods: {
    preview() {
      this.fields = util.getPreviewFields(this.componentInstances)
      this.showPreview = true
    },
    previewMobile() {
      this.fields = util.getPreviewFields(this.componentInstances, true)
      this.showPreviewMobile = true
    },
    editFormProps() {
      this.showFormProps = true
    },
    onValidate(name, status) {
      this.$set(this.validateStatus, name, status)
    },
    hideFormProps(evt) {
      // 校验失败时，不让关闭属性框
      if (!this.isValid) {
        this.$nextTick(() => (this.showFormProps = true))
      }
    },
    checkDbName(rule, value, callback) {
      util.checkDbName(value, callback)
    },
    onPageUnload() {
      crossWindowWatcher.notifyChange(this.fullPath, false)
    },
    checkUnsavedData(event) {
      if (this.isModified()) {
        event.returnValue = '您将会丢失未保存的数据'
      }
    },
    updateDataSaved() {
      this.dataSaved = JSON.stringify(this.getSaveData())
    },
    isModified() {
      return this.dataSaved !== JSON.stringify(this.getSaveData())
    },
    getSaveData() {
      return {
        head: this.formProps,
        fields: util.getFields(this.componentInstances),
      }
    },
    save() {
      const data = this.getSaveData()
      this.saving = true
      let promise
      if (this.formProps.id) {
        // 有id，保存已有的
        promise = axios.put('api/xcoa-mobile/v1/onlineform/editAll', data)
      } else {
        // 保存新的
        promise = axios.post('api/xcoa-mobile/v1/onlineform/addAll', data).then((res) => {
          this.$router.replace({ params: { id: res.data.head.id } })
          return res
        })
      }
      promise
        .finally(() => (this.saving = false))
        .then((res) => {
          this.designer.updateData(res.data)
          crossWindowWatcher.notifyChange(true)
          message.success('保存成功')
          this.updateDataSaved()
        })
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
.preview {
  // antd居中有bug，强制覆盖
  /* stylelint-disable-next-line  */
  top: 0 !important;
  :global(.ant-modal-body) {
    height: 100vh;
    max-height: none;
    padding: 0;
  }
}
.preview-mobile {
  // antd居中有bug，强制覆盖
  /* stylelint-disable-next-line  */
  top: 0 !important;
  :global(.ant-modal-body) {
    max-height: none;
    padding-top: 0;
    padding-bottom: 0;
  }
  :global(.ant-modal-content) {
    background-color: transparent;
    box-shadow: none;
  }

  :global .ant-modal-close {
    top: -20px;
    right: 50px;
    .anticon {
      padding: 5px;
      background-color: $white;
      border-radius: 50%;
    }
  }
}
</style>
