<!--
@ 作者: 秦东
@ 时间: 2023-05-26 10:35:30
@ 备注: 
-->
<script lang='ts' setup>
import '@/assets/scss/element-var.scss'
import '@/assets/scss/index.scss'
import '@/assets/iconfont/iconfont.css'

import { useDesignFormStore } from '@/store/DesignForm/designForm'
import { useRoute, useRouter } from 'vue-router'
import {
    json2string,
    objToStringify,
    string2json,
    stringToObj
  } from '@/utils/DesignForm/form'

import { getRequest } from '@/api/DesignForm'
import { afterResponse, beforeRequest, onChange } from '@/api/DesignForm/utils'

//引入页面
import DragControl from '@/components/DesignForm/dragControl.vue';
import HeadTools from '@/components/DesignForm/public/headTools.vue';
import FormDesign from '@/components/DesignForm/public/form/form.vue'

const store = useDesignFormStore()
const router = useRouter()
const route: any = useRoute().query || {}
const vueFileEl = ref()

const state = reactive({
    formData: {
      list: [],
      form: {
        size: 'default'
      },
      config: {},
	  
    },
    editor: {},
    loading: false,
    formDataPreview: {},
    previewVisible: false, // 预览窗口
    designType: route.type, // 当前页面设计类型，有效值search
    formDict: {},
    formOtherData: {
      source: route.source || '',
      formName: '未命名表单'
    }
	
})
const drawer = reactive({
    visible: false,
    type: '',
    title: '',
    codeType: '',
    direction: undefined, //弹出方向rtl / ltr
    callback: '',
	content:{}
})

const headToolClick = (type: string) => {
	switch (type) {
		case 'del':
			state.formData.list = []
			store.setActiveKey('')
			store.setControlAttr({})
			break
		case 'eye':
			// 打开预览窗口
			store.setActiveKey('')
			store.setControlAttr({})
			state.previewVisible = true
			// eslint-disable-next-line no-case-declarations
			let stringPreview = objToStringify(state.formData) // 防止预览窗口数据修改影响
			// eslint-disable-next-line no-case-declarations
			const formName = state.formData.form.name
			// eslint-disable-next-line no-case-declarations
			const reg = new RegExp(`get${formName}ControlByName`, 'g')
			stringPreview = stringPreview.replace(
			reg,
			`getPreview${formName}ControlByName`
			)
			state.formDataPreview = stringToObj(stringPreview)
			state.formDataPreview.form.name = `Preview${formName}` // 修改下表单名
			break
		case 'json':
			// 生成脚本预览
			openAceEditDrawer({
			direction: 'rtl',
			content: state.formData,
			title: '可编辑修改或将已生成的脚本粘贴进来'
			})
			break
		case 'save':
			saveData()
			break
		case 'vue':
			vueFileEl.value.open(state.formData)
			break
	}
}
// 将数据保存在服务端
const saveData = () => {
    // 添加校验，没有选择数据源时则必须要配置接口url
    const { addUrl, editUrl, requestUrl } = state.formData.config
    if (
      !state.formOtherData.source &&
      (!addUrl || !editUrl || !requestUrl) &&
      state.designType !== 'search'
    ) {
      ElMessage.error('请选择数据源或配置接口url地址，否则表单无法提交保存')
      return
    }
    let params: any = {
      data: objToStringify(state.formData),
      source: state.formOtherData.source, // 数据源允许在表单属性设置里修改的
      name: state.formOtherData.formName, // 表单名称，用于在显示所有已创建的表单列表里显示
      type: 1, // 1表单 2列表
      dict: json2string(state.formDict)
    }
    let apiKey = 'designSave'
    if (route.id) {
      // 编辑状态 当前记录id
      Object.assign(params, { id: route.id })
      apiKey = 'designEdit'
    }
    // 列表搜索模式下只有修改
    if (state.designType === 'search') {
      params = {
        data: objToStringify(state.formData),
        dict: json2string(state.formDict),
        id: route.id
      }
    }
    state.loading = true
    getRequest(apiKey, params)
      .then((res: any) => {
        ElMessage({
          message: res.message || '保存成功！',
          type: 'success'
        })
        // 根据不同情况跳转到不同地址
        const path = route.redirect || '/design/form/list'
        const query: any = {}
        if (route.redirect && route.redirect.indexOf('?') !== -1) {
          // 带有问号参数时，放在path传是有问题的，将id=1转为{id:1}
          const p = route.redirect.split('?')[1]
          const pSplit = p.split('&')
          pSplit.forEach((item: string) => {
            const splitItem = item.split('=')
            query[splitItem[0]] = splitItem[1]
          })
        }
        router.push({ path: path, query: query })
        state.loading = false
      })
      .catch((res: any) => {
        ElMessage.error(res.message || '保存异常')
        state.loading = false
      })
    // 清空右侧内容管理菜单存在session的内容，刷新时可重新加载新菜单
    if (!route.id) {
      // 新增时
      window.sessionStorage.removeItem('formMenuList')
    }
    // 清空右侧栏信息
    store.setActiveKey('')
    store.setControlAttr({})
}
const openAceEditDrawer = (params: any) => {
    const { type, direction, codeType, title, callback, content } = params
    drawer.direction = direction // 窗口位置ltr/rtl
    drawer.type = type // 作为窗口唯一标识，在窗口关闭时可根据type作不同处理
    drawer.codeType = codeType || '' // 显示代码类型
    drawer.title = title ? `提示：${title}` : ''
    drawer.visible = true
    drawer.callback = callback
    let editData =
      codeType === 'json'
        ? json2string(content, true)
        : objToStringify(content, true)
    switch (type) {
      case 'css':
        editData = state.formData.config?.style || ''
        break
      case 'dict':
        // 格式化一下
        editData = json2string(state.formDict, true)
        break
      case 'beforeRequest':
      case 'beforeSubmit':
      case 'afterResponse':
      case 'afterSubmit':
      case 'change':
        // eslint-disable-next-line no-case-declarations
        const beforeData = state.formData.events || {}
        if (beforeData[type]) {
          editData = objToStringify(beforeData[type], true)
        } else {
          if (['afterResponse', 'afterSubmit'].includes(type)) {
            editData = afterResponse
          } else if (type === 'change') {
            editData = onChange
          } else {
            editData = beforeRequest
          }
        }
        break
      // case 'afterResponse':
      // case 'afterSubmit':
      //   const newData = state.formData.events || {}
      //   if (newData[type]) {
      //     editData = objToStringify(newData[type], true)
      //   } else {
      //     editData = afterResponse
      //   }
      //   break

      case 'optionsParams':
        if (!content) {
          editData = beforeRequest
        }
        break
      case 'optionsResult':
        if (!content) {
          editData = afterResponse
        }
        break
    }
    drawer.content = editData
}
</script>
<template>
	<div class="design-container">
		<DragControl />
		<div class="main-body">
			<HeadTools @click="headToolClick" />
			<div class="main-form" v-loading="state.loading">
				<div class="empty-tips" v-if="state.formData.list.length === 0">
					从左侧拖拽来添加字段
				</div>
				<FormDesign 
					:type="5"
          :formData="state.formData"
          :dict="state.formDict"
				/>
			</div>
		</div>
	</div>
</template>
<style  lang='scss' scoped>

</style>
