<template>
  <a-config-provider :locale="locale">
    <div class="form-designer-container-9136076486841527">
      <k-header
        :baseOptions="data.config.seniorSetting.baseOptions"
        @handleSave="handleSave"
        @handleShare="handleOpenShareModal"
        @back="back"
        v-if="showHead"
        :title="title"
      />
      <a-spin size="large" :spinning="loading">
        <!--tabs操作区域start-->
        <tabArea>
          <!-- 顶部操作区域 start -->
          <operatingArea
            v-if="toolbarsTop && showOperatingArea"
            :showToolbarsText="showToolbarsText"
            :toolbars="toolbars"
            @handleSave="handleSave"
            @handlePreview="handlePreview"
            @handleOpenImportJsonModal="handleOpenImportJsonModal"
            @handleOpenCodeModal="handleOpenCodeModal"
            @handleOpenJsonModal="handleOpenJsonModal"
            @handleReset="handleReset"
            @handleClose="handleClose"
          >
            <template slot="left-action">
              <slot name="left-action"></slot>
            </template>

            <template slot="right-action">
              <slot name="right-action"></slot>
            </template>
          </operatingArea>
          <!-- 顶部操作区域 end -->

          <template slot="form_generate">
            <slot name="form_generate">
              <div
                class="content"
                :class="{
                  'show-head': showHead,
                  'toolbars-top': toolbarsTop,
                  'show-head-and-toolbars-top': toolbarsTop && showHead
                }"
              >
                <!-- 左侧控件区域 start -->
                <aside class="left">
                  <a-collapse @change="collapseChange" :defaultActiveKey="collapseDefaultActiveKey">
                    <!-- 基础控件 start -->
                    <a-collapse-panel v-if="basicsArray.length > 0" header="基础控件" key="1">
                      <collapseItem
                        :list="basicsArray"
                        @generateKey="generateKey"
                        @handleListPush="handleListPush"
                        @start="handleStart"
                      />
                    </a-collapse-panel>
                    <!-- 基础控件 end -->

                    <!-- 自定义控件 start -->
                    <a-collapse-panel v-if="customComponents.list.length > 0" :header="customComponents.title" key="3">
                      <collapseItem
                        :list="customComponents.list"
                        @generateKey="generateKey"
                        @handleListPush="handleListPush"
                        @start="handleStart"
                      />
                    </a-collapse-panel>
                    <!-- 自定义控件 end -->

                    <!-- 布局控件 start -->
                    <a-collapse-panel v-if="layoutArray.length > 0" header="布局控件" key="4">
                      <collapseItem
                        :list="layoutArray"
                        @generateKey="generateKey"
                        @handleListPush="handleListPush"
                        @start="handleStart"
                      />
                    </a-collapse-panel>
                    <!-- 布局控件 end -->
                  </a-collapse>
                </aside>
                <!-- 左侧控件区域 end -->

                <!-- 中间面板区域 start -->
                <section style="flex:1">
                  <!-- 内容区操作区域 start -->
                  <operatingArea
                    v-if="!toolbarsTop && showOperatingArea"
                    :showToolbarsText="showToolbarsText"
                    :toolbars="toolbars"
                    @handleSave="handleSave"
                    @handlePreview="handlePreview"
                    @handleOpenImportJsonModal="handleOpenImportJsonModal"
                    @handleOpenCodeModal="handleOpenCodeModal"
                    @handleOpenJsonModal="handleOpenJsonModal"
                    @handleReset="handleReset"
                    @handleClose="handleClose"
                  >
                    <template slot="left-action">
                      <slot name="left-action"></slot>
                    </template>

                    <template slot="right-action">
                      <slot name="right-action"></slot>
                    </template>
                  </operatingArea>
                  <!-- 内容区操作区域 end -->

                  <k-form-component-panel
                    :class="{ 'no-toolbars-top': !toolbarsTop }"
                    :data="data"
                    :selectItem="selectItem"
                    :noModel="noModel"
                    :hideModel="hideModel"
                    :startType="startType"
                    ref="KFCP"
                    @handleSetSelectItem="handleSetSelectItem"
                  />
                  <!-- 操作区域 start -->
                  <k-json-modal ref="jsonModal" />
                  <k-code-modal ref="codeModal" />
                  <importJsonModal ref="importJsonModal" />
                  <shareModal ref="shareModal" :pid="pid" />
                </section>
                <!-- 中间面板区域 end -->

                <!-- 右侧控件属性区域 start -->
                <aside class="right" v-show="selectItem.key !== ''">
                  <formItemProperties
                    :class="{ 'show-properties': showPropertie }"
                    class="form-item-properties"
                    :selectItem="selectItem"
                    :hideModel="hideModel"
                    @handleHide="showPropertie = false"
                  />
                </aside>
                <!-- 右侧控件属性区域 end -->
              </div>
            </slot>
          </template>

          <!-- 主题设置区域 start -->
          <template slot="theme_setting">
            <slot name="theme_setting">
              <KFormThemeSettings :data="data" :previewOptions="previewOptions" />
            </slot>
          </template>
          <!-- 主题设置区域 end -->

          <!-- 预览区域 start -->
          <template slot="preview">
            <slot name="preview">
              <previewModal ref="previewModal" :jsonData="data" />
            </slot>
          </template>
          <!-- 预览区域 end -->

          <!-- 高级设置区域 start -->
          <template slot="senior_setting">
            <slot name="senior_setting">
              <KFormSeniorSettings :config="data.config.seniorSetting" />
            </slot>
          </template>
          <!-- 高级设置区域 end -->
        </tabArea>
        <!--tabs操作区域end-->
        <!-- <k-footer /> -->
      </a-spin>
    </div>
  </a-config-provider>
</template>
<script>
import kHeader from './module/header'
import tabArea from './module/tabArea'
import kCodeModal from './module/codeModal'
import kJsonModal from './module/jsonModal'
import shareModal from './module/shareModal'
import collapseItem from './module/collapseItem'
import operatingArea from './module/operatingArea'
import formProperties from './module/formProperties'
import previewModal from '../KFormPreview/index.vue'
import importJsonModal from './module/importJsonModal'
import formItemProperties from './module/formItemProperties'
import kFormComponentPanel from './module/formComponentPanel'
import { getFormDetailPage, editFormDetailPage } from '@/api/common.js'
import { basicsList, layoutList, customComponents } from './config/formItemsConfig'

import isEqual from 'lodash/isEqual'
import cloneDeep from 'lodash/cloneDeep'
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'

export default {
  name: 'KFormDesign',
  props: {
    title: {
      type: String,
      default: '表单设计器'
    },
    showHead: {
      type: Boolean,
      default: true
    },
    showOperatingArea: {
      type: Boolean,
      default: false
    },
    toolbarsTop: {
      type: Boolean,
      default: true
    },

    toolbars: {
      //工具栏中按钮配置
      type: Array,
      default: () => ['save', 'preview', 'importJson', 'exportJson', 'exportCode', 'reset', 'close']
    },
    showToolbarsText: {
      type: Boolean,
      default: true
    },
    fields: {
      //在左侧控件区域显示的字段
      type: Array,
      default: () => [
        'banner',
        'input',
        'textarea',
        'number',
        'select',
        'checkbox',
        'radio',
        'date',
        'time',
        'rate',
        'switch',
        'uploadImg',
        'cascader',
        'alert',
        'text',
        'divider',
        'segmentation',
        'card',
        'grid',
        'table'
        // 'slider',
        // 'uploadFile',
        // 'treeSelect',
        // 'batch',
        // 'editor',
        // 'button',
        // 'html',
      ]
    },
    hideModel: {
      // 隐藏数据字段
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      locale: zhCN,
      customComponents,
      updateTime: 0,
      updateRecordTime: 0,
      showPropertie: false,
      startType: '',
      noModel: ['button', 'divider', 'card', 'grid', 'table', 'alert', 'text', 'html', 'segmentation'], //不需要model字段的属性
      data: {
        list: [],
        config: {
          themeSetting: {
            marginTop: 20, //距离顶部距离
            backgroundImage: '',
            submitButtonText: '提交', //按钮文字
            backgroundSize: 'cover',
            backgroundPosition: 'center',
            backgroundColor: '#fff',
            hideRequiredMark: false //隐藏必选标记
          },
          seniorSetting: {
            baseOptions: {
              innerTitle: '表单提交', //内部名称
              wrapperTitle: '表单提交' //外部名称
            },
            limitOptions: {
              //提交限制
              timeStatus: false,
              setBeginTime: false, //是否设置开始时间
              setEndTime: false, //是否设置结束时间
              begin_time: '', //开始时间
              end_time: '', //结束时间
              beforeBeginText: '', //开始时间提示文字
              afterEndText: '', //结束时间提示文字
              //默认结束时间提示文字
              defaultAfterEndText:
                '<div><img style="display: block; margin-left: auto; margin-right: auto;" src="https://abcms.intcolon.com/assets/484b1e1a-69ec-445f-91dd-45709e981a5e.png" alt="" width="330px" height="334" /></div>\n<p style="text-align: center; line-height: 2;"><span style="font-size: 22px;"><strong>&nbsp;问卷已结束，感谢参与！</strong></span></p>',
              //默认开始时间提示文字
              defaultBeforeBeginText:
                '<div><img style="display: block; margin-left: auto; margin-right: auto;" src="https://abcms.intcolon.com/assets/484b1e1a-69ec-445f-91dd-45709e981a5e.png" alt="" width="330px" height="334" /></div>\n<p style="text-align: center; line-height: 2;"><span style="font-size: 22px;"><strong>&nbsp;问卷暂未开始！</strong></span></p>',
              singleSubmit: false, //单次提交
              onlyWx: false //仅在微信环境下提交
            },
            shareOptions: {
              //分享配置
              status: false,
              banSharing: false,
              title: '',
              desc: '',
              imgUrl: ''
            },
            policyOptions: {
              //隐私政策配置
              status: false,
              guideText: '我已阅读并同意',
              mainText: '隐私条款',
              policyRichText: ''
            },
            afterSubmitOptions: {
              //提交后配置
              status: false,
              type: 'url',
              linkUrl: '',
              afterSubmitText: '',
              defaultAfterSubmitText:
                '<div><img style="display: block; margin-left: auto; margin-right: auto;" src="https://abcms.intcolon.com/assets/484b1e1a-69ec-445f-91dd-45709e981a5e.png" alt="" width="330px" height="334" /></div>\n<p style="text-align: center; line-height: 2;"><span style="font-size: 22px;"><strong>&nbsp;提交成功！</strong></span></p>'
            }
          }
        }
      },
      previewOptions: {},
      selectItem: {
        //当前选中的表单
        key: ''
      },
      loading: false,
      backUpData: {}, //进入时获取的数据或者保存后的数据，用做退出时判断是否修改过表单
      pid: '' //表单id
    }
  },
  components: {
    kHeader,
    tabArea,
    kJsonModal,
    kCodeModal,
    shareModal,
    collapseItem,
    previewModal,
    operatingArea,
    formProperties,
    importJsonModal,
    formItemProperties,
    kFormComponentPanel
  },
  computed: {
    basicsArray() {
      // 计算需要显示的基础字段
      return basicsList.filter(item => this.fields.includes(item.type))
    },
    layoutArray() {
      // 计算需要显示的布局字段
      return layoutList.filter(item => this.fields.includes(item.type))
    },
    collapseDefaultActiveKey() {
      // 计算当前展开的控件列表
      const defaultActiveKey = window.localStorage.getItem('collapseDefaultActiveKey')
      if (defaultActiveKey) {
        return defaultActiveKey.split(',')
      } else {
        return ['1']
      }
    }
  },
  methods: {
    handleOk(e) {
      setTimeout(() => {
        this.modalvisible = false
      }, 1000)
    },
    handleCancel(e) {
      this.modalvisible = false
    },
    generateKey(list, index) {
      // 生成key值
      const key = list[index].type + '_' + new Date().getTime()
      this.$set(list, index, {
        ...list[index],
        key,
        model: key
      })
      if (this.noModel.includes(list[index].type)) {
        // 删除不需要的model属性
        delete list[index].model
      }
    },

    handleListPush(item) {
      console.log(item)
      // 双击控件按钮push到list
      // 生成key值
      if (!this.selectItem.key) {
        // 在没有选择表单时，将数据push到this.data.list
        const key = item.type + '_' + new Date().getTime()
        item = {
          ...item,
          key,
          model: key
        }
        if (this.noModel.includes(item.type)) {
          // 删除不需要的model属性
          delete item.model
        }
        // const itemString = JSON.stringify(item)
        // const record = JSON.parse(itemString)
        const record = cloneDeep(item)
        // 删除icon及compoent属性
        delete record.icon
        delete record.component
        this.data.list.push(record)
        this.handleSetSelectItem(record)
        return false
      }
      this.$refs.KFCP.handleCopy(false, item)
    },
    handleOpenJsonModal() {
      // 打开json预览模态框
      this.$refs.jsonModal.jsonData = this.data
      this.$refs.jsonModal.visible = true
    },
    async handleOpenShareModal() {
      // 打开生成表单模态框
      const response = await this.handleSave()
      console.log(response)
      if (response && response.data) {
        console.log(response.data)
        this.$refs.shareModal.content = `${process.env.VUE_APP_FORMPARSER_URL}?formId=` + this.pid
        this.$refs.shareModal.visible = true
      }
    },
    handleOpenImportJsonModal() {
      // 打开json预览模态框
      this.$refs.importJsonModal.jsonData = this.data
      this.$refs.importJsonModal.handleSetSelectItem = this.handleSetSelectItem
      this.$refs.importJsonModal.visible = true
    },
    handlePreview() {
      // 打开预览模态框
      this.$refs.previewModal.visible = true
    },
    handleReset() {
      // 清空
      this.$confirm({
        title: '警告',
        content: '是否确认清空内容?',
        okText: '是',
        okType: 'danger',
        cancelText: '否',
        onOk: () => {
          this.data.list = []
          this.handleSetSelectItem({ key: '' })
          this.$message.success('已清空')
        }
      })
    },
    handleSetSelectItem(record) {
      console.log(record)
      // 操作间隔不能低于100毫秒
      const newTime = new Date().getTime()
      if (newTime - this.updateTime < 100) {
        return false
      }

      this.updateTime = newTime

      // 设置selectItem的值
      this.selectItem = record

      // 判断是否选中控件，如果选中则弹出属性面板，否则关闭属性面板
      if (record.key) {
        this.startType = record.type
        this.showPropertie = true
      } else {
        this.showPropertie = false
      }
    },
    handleSetData(data) {
      // 用于父组件赋值
      try {
        if (typeof data !== 'object') {
          return false
        } else {
          this.data = data
          // 导入json数据后，需要清除已选择key
          this.handleSetSelectItem({ key: '' })
        }
        return true
      } catch (error) {
        console.error(error)
        return false
      }
    },
    collapseChange(val) {
      // 点击collapse时，保存当前collapse状态
      window.localStorage.setItem('collapseDefaultActiveKey', val)
    },
    handleStart(type) {
      this.startType = type
    },
    async handleSave(callback = () => {}) {
      // 保存函数
      this.loading = true
      try {
        const config = this.data.config
        const res = await editFormDetailPage(
          {
            pid: this.pid,
            title: config.seniorSetting.baseOptions.innerTitle,
            sub_title: config.seniorSetting.baseOptions.wrapperTitle,
            conf_content: JSON.stringify(this.data),
            begin_time: config.seniorSetting.limitOptions.begin_time || null,
            end_time: config.seniorSetting.limitOptions.end_time || null
          },
          this.pid
        )
        this.backUpData = cloneDeep(this.data)
        this.loading = false
        this.$message.success({
          content: '保存成功',
          duration: 1.5,
          onClose() {
            callback()
          }
        })

        return res
      } catch (error) {
        this.loading = false
        this.$message.error({
          content: error.message,
          duration: 1.5
        })
      }
    },
    handleClose() {
      this.$emit('close')
    },
    back() {
      if (isEqual(this.backUpData, this.data)) {
        this.$router.push('/home')
        return
      }
      const that = this
      this.$confirm({
        title: '确定退出编辑？',
        okText: '退出',
        cancelText: '退出并保存',
        onCancel() {
          console.log('退出并保存')
          that.handleSave(() => {
            that.$router.push('/home')
          })
        },
        onOk() {
          that.$router.push('/home')
        }
      })
    },

    goBack() {
      history.pushState(null, null, document.URL)
      this.back()
    },

    //用于向已生成的表单再次编辑时填充新增加的配置项，遍历当前data的config
    fillNewOptions(initConfig, jsonConfig) {
      for (const key in initConfig) {
        if (initConfig[key] && typeof initConfig[key] === 'object' && initConfig[key] !== null) {
          if (jsonConfig[key] === undefined) {
            jsonConfig[key] = initConfig[key]
          } else {
            this.fillNewOptions(initConfig[key], jsonConfig[key])
          }
        } else {
          if (jsonConfig[key] === undefined) {
            jsonConfig[key] = initConfig[key]
          }
        }
      }
    }
  },
  async created() {
    this.pid = this.$route.params.id
    try {
      //获取表单数据
      this.loading = true
      const result = await getFormDetailPage({}, this.pid)
      if (result.data && result.data.conf_content) {
        //已经编辑过
        const cloneData = JSON.parse(result.data.conf_content)
        cloneData.config.seniorSetting.baseOptions.innerTitle = result.data.title
        cloneData.config.seniorSetting.baseOptions.wrapperTitle = result.data.sub_title
        this.fillNewOptions(this.data.config, cloneData.config)
        this.backUpData = cloneDeep(cloneData)
        this.data = cloneData
      } else {
        //第一次编辑
        this.data.config.seniorSetting.baseOptions.innerTitle = result.data.title
        this.data.config.seniorSetting.baseOptions.wrapperTitle = result.data.sub_title
      }
      this.loading = false
    } catch (error) {
      this.loading = false
    }
  },
  mounted() {
    //监听浏览器返回
    if (window.history && window.history.pushState) {
      history.pushState(null, null, document.URL)
      window.addEventListener('popstate', this.goBack, false)
    }
  },
  destroyed() {
    window.removeEventListener('popstate', this.goBack, false)
  }
}
</script>
<style scoped>
.copy-btn {
  height: 23px;
  margin-left: 20px;
}
</style>
