<!--
@ 作者: 秦东
@ 时间: 2024-03-11 09:01:36
@ 备注: 自定义表单
-->
<script lang='ts' setup>
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 { ref, reactive, provide, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { useLayoutStore } from '@/store/DesignForm/layout'
import { FormData,formStruct,DrawerStruct, VideoMsg } from '@/api/DesignForm/types'
import { customerFormVersionCont } from '@/api/DesignForm/type'
import { saveProductionForm,getOneProductionForm,haveCustomerFormVersion,editCustomerFormInfo,saveAsNewVersion,enableVersion,judgeSubmitCancel } from '@/api/DesignForm/requestapi'
import { submitAndCancelButton,cancelButton,submitButton } from "@/api/DesignForm/gromGround/data";

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

const props = defineProps({
	formKey:{
		type:String,
		default:""
	},
  	formconfigcont:{
		type:Object,
		default(){
			return {}
		}
	},
	state:{
		type:Object,
		default(){
			return {}
		}
	}
});

const emits = defineEmits<{
    (e: 'update:state', val: formStruct): void
	(e: 'judgeFormIsEdit', val: boolean): void
	(e: 'runNextWindows', val: number): void
	(e: 'closeFormPage'): void
}>()

const state =  computed({
	get() {
		return props.state
	},
	set(val: formStruct) {
		emits('update:state', val)
	}
});
// 当前表单设计类型，供各子组件调用以展示不同页面，统一方式不需要每个组件都从路由中取
provide('formDesignType', state.value.designType)
const vueFileEl = ref()
const formControlAttrEl = ref()
const drawer = reactive<DrawerStruct>({
    visible: false,
    type: '',
    title: '',
    codeType: '',
    direction: undefined, //弹出方向rtl / ltr
    callback: ''
})
const versionCont = ref<customerFormVersionCont[]>([])			//版本内容列表
const versionId = ref<string>("")		//版本号
const store = useDesignFormStore()
const router = useRouter()
const route: any = useRoute().query || {}

// 搜索设计时左侧快速添加字段
const searchCheckField = (data: FormData) => {
    state.value.formData.list.push(data)
}
// 选择模板
const selectTemplate = (data: FormData) => {
	state.value.formData = stringToObj(objToStringify(data))
}
//编辑版本状态
const editversionstaus = (id:string) =>{
	// console.log("编辑版本状态--1--》",id)
	enableVersion({id:id.toString()})
		.then(() =>{
			haveCustomerFormVersion({id:state.value.formData.form.name})
						.then(({data})=>{
							// console.log("加载异常-------------->",data)
							versionCont.value = data
							if(data.length > 0){
								data.forEach((item:any) => {
									if(item.status == 1){
										versionId.value = item.id.toString()
									}
								});
							}
						})
		})
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 16:10:23
@ 功能: 按钮操作
*/
const headToolClick = (type: string) => {
	switch (type) {
		case 'del':	//清空
			state.value.formData.list = []
			store.setActiveKey('')
			store.setControlAttr({})
			break
		case 'eye':	//预览
			store.setActiveKey('')
			store.setControlAttr({})
			let stringPreview = objToStringify(state.value.formData) // 防止预览窗口数据修改影响
			const formName = state.value.formData.form.name
			const reg = new RegExp(`get${formName}ControlByName`, 'g')
			stringPreview = stringPreview.replace(
				reg,
				`getPreview${formName}ControlByName`
			)
			state.value.formDataPreview = stringToObj(stringPreview)
			state.value.formDataPreview.form.name = `Preview${formName}` // 修改下表单名
			// console.log("预览数据",state.value.formDataPreview);
			state.value.previewVisible = true
			break
		case 'json': // 生成脚本预览
			openAceEditDrawer({
				direction: 'rtl',
				content: state.value.formData,
				title: '可编辑修改或将已生成的脚本粘贴进来'
			})
			break
		case 'save':			//保存
			// saveData();
			if(props.formKey != ""){
				editSaveData();
			}else{
				saveDataNew();
			}	
			break
		case 'branch':			//另存为新版
			saveOtherData();
			break
		case 'vue':
			vueFileEl.value.open(state.value.formData)
			break
		case 'close':
			state.value.formData.list = []
			store.setActiveKey('')
			store.setControlAttr({})
			emits('closeFormPage')
			// if(state.value.formData.list.length > 0){
			// 	ElMessageBox.confirm('表单已做设计或修改！请问是否保存？','温馨提示！',{
			// 		confirmButtonText: '保存',
			// 		cancelButtonText: '不保存',
			// 		type: 'warning',
			// 		draggable: true,
			// 	})
			// 		.then(() => {
			// 			saveDataNew();
			// 		})
			// 		.catch(() => {
			// 			state.value.formData.list = []
			// 			store.setActiveKey('')
			// 			store.setControlAttr({})
			// 			// emits("update:draweropenclose", false);
			// 			emits("closeDrawer");
			// 		})
			// }else{
			// 	state.value.formData.list = []
			// 	store.setActiveKey('')
			// 	store.setControlAttr({})
			// 	emits('closeFormPage')
			// }
			break
	}
}
/**
@ 作者: 秦东
@ 时间: 2024-03-11 13:44:38
@ 功能: 另存为新版本
*/
const saveOtherData = () => {
	let params: any = {
		jsondata:JSON.stringify(state.value.formData),
		data: objToStringify(state.value.formData),
		source: state.value.formOtherData.source, // 数据源允许在表单属性设置里修改的
		name: state.value.formOtherData.formName, // 表单名称，用于在显示所有已创建的表单列表里显示
		type: 1, // 1表单 2列表
		dict: json2string(state.value.formDict)
	}
	state.value.loading = true
	saveAsNewVersion(params)
		.then((res: any) => {
			// console.log("数据保存", res)
			if(res.code == 0){
				emits('judgeFormIsEdit', false)
				ElMessage({
					message: res.message || '保存成功！',
					type: 'success'
				})
				// emits("handlequery");
				// emits("update:draweropenclose", false);
				emits("runNextWindows",2);
				// 清空右侧栏信息
				store.setActiveKey('')
				store.setControlAttr({})
			}else{
				ElMessage({
					message: res.msg || '保存失败！',
					type: 'error'
				})
			}
      
		})
		.finally(() => {
			state.value.loading=false;
		})
		.catch((res: any) => {
			ElMessage.error(res.message || '保存异常')
			state.value.loading = false
		})
}


//讲数据保存到服务端(新版)
const saveDataNew = () => {
	
	let params: any = {
		jsondata:JSON.stringify(state.value.formData),
		data: objToStringify(state.value.formData),
		source: state.value.formOtherData.source, // 数据源允许在表单属性设置里修改的
		name: state.value.formOtherData.formName, // 表单名称，用于在显示所有已创建的表单列表里显示
		type: 1, // 1表单 2列表
		dict: json2string(state.value.formDict)
	}
	let apiKey = 'designSave'
	if (route.id) {
		// 编辑状态 当前记录id
		Object.assign(params, { id: route.id })
		apiKey = 'designEdit'
	}
  // 列表搜索模式下只有修改
	if (state.value.designType === 'search') {
		params = {
			data: objToStringify(state.value.formData),
			dict: json2string(state.value.formDict),
			id: route.id
		}
	}
	state.value.loading = true

	saveProductionForm(params)
		.then((res: any) => {
			// console.log("数据保存", res)
			if(res.code == 0){
				emits('judgeFormIsEdit', false)
				ElMessage({
					message: res.message || '保存成功！',
					type: 'success'
				})
				// emits("handlequery");
				// emits("update:draweropenclose", false);
				emits("runNextWindows",2);
				// 清空右侧栏信息
				store.setActiveKey('')
				store.setControlAttr({})
			}else{
				ElMessage({
					message: res.msg || '保存失败！',
					type: 'error'
				})
			}
      
		})
		.finally(() => {
			state.value.loading=false;
		})
		.catch((res: any) => {
			ElMessage.error(res.message || '保存异常')
			state.value.loading = false
		})
}
//编辑自定义表单数据
const editSaveData = () =>{
	let params: any = {
		jsondata:JSON.stringify(state.value.formData),
		data: objToStringify(state.value.formData),
		source: state.value.formOtherData.source, // 数据源允许在表单属性设置里修改的
		name: state.value.formOtherData.formName, // 表单名称，用于在显示所有已创建的表单列表里显示
		type: 1, // 1表单 2列表
		dict: json2string(state.value.formDict),
		id:props.formKey.toString(),
		version:versionId.value.toString(),
	}
	state.value.loading = true
	editCustomerFormInfo(params)
		.then((res: any) => {
			if(res.code == 0){
				emits('judgeFormIsEdit', false)
				ElMessage({
					message: res.message || '保存成功！',
					type: 'success'
				})
				// emits("handlequery");
				// emits("update:draweropenclose", false);
				emits("runNextWindows",2);
				// 清空右侧栏信息
				store.setActiveKey('')
				store.setControlAttr({})
			}else{
				ElMessage({
					message: res.msg || '保存失败！',
					type: 'error'
				})
			}
		})
		.finally(() => {
			state.value.loading=false;
		})
		.catch((res: any) => {
			ElMessage.error(res.message || '保存异常')
			state.value.loading = false
		})
}


//打开脚本预览
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.value.formData.config?.style || ''
			break
		case 'dict':
			// 格式化一下
			editData = json2string(state.value.formDict, true)
			break
		case 'beforeRequest':
		case 'beforeSubmit':
		case 'afterResponse':
		case 'afterSubmit':
		case 'change':
			// eslint-disable-next-line no-case-declarations
			const beforeData = state.value.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
}
//关闭脚本预览窗，并初始化脚本预览参数
const dialogCancel = () => {
    drawer.visible = false
    drawer.type = ''
    drawer.title = ''
    drawer.codeType = ''
    drawer.callback = ''
    drawer.content = ''
}
// 弹窗确认
const dialogConfirm = (editVal: string) => {
    // 生成脚本预览和导入json，都是将编辑器内容更新至state.formData
    try {
      	if (typeof drawer.callback === 'function') {
			// callback
			const newObj =
			drawer.codeType === 'json'? string2json(editVal): stringToObj(editVal)
			drawer.callback(newObj)
      	} else {
			switch (drawer.type) {
				case 'css':
					// 表单属性－编辑表单样式
					if (!state.value.formData.config) {
						state.value.formData.config = {}
					}
					state.value.formData.config.style = editVal
					break
				case 'dict':
					state.value.formDict = string2json(editVal)
					break
				case 'beforeRequest':
				case 'beforeSubmit':
				case 'afterResponse':
				case 'afterSubmit':
				case 'closeSubmit':
				case 'change':
					if (!state.value.formData.events) {
						state.value.formData.events = {}
					}
					state.value.formData.events[drawer.type] = stringToObj(editVal)
					break
				default:
					state.value.formData = stringToObj(editVal)
			}
      	}
      	dialogCancel()
    } catch (res) {
		// console.log(res.message)
		//ElMessage.error(res.message)
    }
}
// 预览窗口提交测试
const previewForm = ref()
const previewSubmit = () => {
    previewForm.value.validate((valid: boolean, fields: any) => {
		if (valid) {
			// alert('校验通过')
			ElMessage.success('校验通过')
			// console.log(fields)
		} else {
			// alert('校验不通过')
			// console.log('error submit!', fields)
			ElMessage.error('校验不通过')
			return false
      	}
    })
}
/**
@ 作者: 秦东
@ 时间: 2024-03-11 15:12:03
@ 功能: 获取表单内容
*/
const getInitData = ()	=> {
	if (props.formKey) {
		state.value.loading = true
		getOneProductionForm({id: props.formKey.toString()})
			.then((res:any) => {
				if(res.code == 0){
					const result = res.data
					// 初始设计搜索时res.data=''
					if (result.mastesform) {
						state.value.formData = stringToObj(result.mastesform)
					}
					state.value.formDict = string2json(result.dict)
					// 恢复表单名称
					state.value.formOtherData.source = result.source
					state.value.formOtherData.formName = result.name

					state.value.formOtherData.formName = result.name
					state.value.formData.form.name = result.tablekey
					state.value.formData.form.formName = result.name
					if (result.source && state.value.designType !== 'search') {
						// 加载属性侧边栏的字段标识，搜索时不需要请求
						formControlAttrEl.value.getFormFieldBySource(result.source)
					}
				}else{
					ElMessage.error(res.msg || '加载异常')
				}
				state.value.loading = false
			})
			.finally(()=>{
				
				haveCustomerFormVersion({id:state.value.formData.form.name})
				.then(({data})=>{
					versionCont.value = data
					if(data.length > 0){
						data.forEach((item:any) => {
							if(item.status == 1){
								versionId.value = item.id.toString()
							}
						});
					}
				})
			})
			.catch((res: any) => {
				// console.log(res)
				ElMessage.error(res.msg || '加载异常')
				state.value.loading = false
			})
	}
}
onMounted(() => {
    if (route.source) {
      	formControlAttrEl.value.getFormFieldBySource(route.source)
    }
	getInitData()
})
</script>
<template>
	<div class="design_container">
		<DragControl
			v-model:versionid="versionId"
			:formid="state.formOtherData.source"
			:versioncont="versionCont"
      		@click-check="searchCheckField"
      		@click="selectTemplate"
			@editversionstaus="editversionstaus"
		/>
		<div class="main-body">
			<HeadTools v-loading="state.loading" :customerformid="props.formKey" @click="headToolClick" />
			<div v-loading="state.loading" class="main-form">
				<div v-if="state.formData.list.length === 0" class="empty-tips">
					从左侧拖拽来添加组件
				</div>
				<FormDesign 
					:type="5"
					:form-data="state.formData"
					:dict="state.formDict"
				/>
			</div>
		</div>
		<form-control-attr
			ref="formControlAttrEl"
			v-model:formOtherData="state.formOtherData"
			:form-data="state.formData.form"
			:form-config="state.formData.config"
			:customerformid="props.formKey"
			:form-list="state.formData.list"
			@open-dialog="openAceEditDrawer"
		/>
		<ace-drawer
			v-model="drawer.visible"
			:title="drawer.title"
			:direction="drawer.direction"
			:content="drawer.content"
			:code-type="drawer.codeType"
			@before-close="dialogCancel"
			@confirm="dialogConfirm"
		/>
		<vue-file v-if="!['search'].includes(state.designType)" ref="vueFileEl" />
		<el-drawer
			v-model="state.previewVisible"
			title="预览"
			:append-to-body="true"
			size="50%"
		>
			<form-design
				v-if="state.previewVisible"
				ref="previewForm"
				:form-data="state.formDataPreview"
				:dict="state.formDict"
				:type="1"
			/>
			<template #footer>
				<div class="dialog-footer">
					<el-button size="small" type="primary" @click="previewSubmit">
						提交
					</el-button>
					<el-button size="small" @click="state.previewVisible = false">
						取消
					</el-button>
				</div>
			</template>
      	</el-drawer>
	</div>
</template>
<style  lang='scss' scoped>
.design_container{
	display: flex;
    background-color: #FFFFFF;
	
}
</style>
