<template>
	<div class="by-form">
		<el-form
			:model="formData"
			:label-width="formOption.labelWidth"
			:inline="formOption.inline || false"
			:rules="rules"
			:labelPosition="formOption.labelPosition || 'top'"
			ref="byForm"
		>
			<el-form-item
				:label="i.label"
				v-for="i in formConfig"
				:key="i.model"
				:prop="i.prop"
				:style="
					i.type == 'title' ? 'width:100%' :
						i.itemWidth
						? 'width:' + i.itemWidth + '%'
						: formOption.itemWidth
						? 'width:' + formOption.itemWidth + '%'
						: '100%'
				"
				:class="i.isHide ? 'dn' : ''"
			>
				<el-input
					v-if="i.type == 'input'"
					v-model="formData[i.prop]"
					:placeholder="i.placeholder || '请输入'"
					@input="((e)=>commonsEmit(e,i))"
					:type="i.itemType ? i.itemType : 'text'"
					:disabled="i.disabled ? i.disabled : false"
					:max="i.max"
					:min="i.min"
					:maxlength="i.maxlength"
				/>
				<el-select
					v-model="formData[i.prop]"
					:multiple="i.multiple || false"
					v-else-if="i.type == 'select'"
					:placeholder="i.placeholder || '请选择'"
					@change="((e)=>commonsEmit(e,i))"
					:disabled="i.disabled ? i.disabled : false"
					:style="i.style"
				>
					<el-option :label="j.title || j.name || j.label" :value="j.id || j.value" v-for="j in i.data" :key="j.id">
					</el-option>
				</el-select>
				<el-tree-select
					v-model="formData[i.prop]"
					v-else-if="i.type == 'treeSelect'"
					:data="i.data"
					:props="{ value: 'id', label: 'label', children: 'children' }"
					value-key="id"
					:placeholder="i.placeholder || '请选择'"
					check-strictly
				/>
				<el-date-picker
					v-model="formData[i.prop]"
					v-else-if="i.type == 'date'"
					:type="i.itemType"
					:placeholder="i.placeholder || '请选择时间'"
					@change="commonsEmit"
					:disabled="i.disabled ? i.disabled : false"
					:format="i.format ? i.format : dateFormatInit(i.itemType)"
      				:value-format="i.format ? i.format : dateFormatInit(i.itemType)"
				/>
				<el-switch
					:disabled="i.disabled ? i.disabled : false"
					v-else-if="i.type == 'switch'"
					v-model="formData[i.prop]"
				/>
				<el-checkbox-group
					v-else-if="i.type == 'checkbox'"
					v-model="formData[i.prop]"
					:disabled="i.disabled ? i.disabled : false"
				>
					<el-checkbox  v-for="j in i.data" :key="j.id || j.value" ::label="j.id  || j.value" name="type">
						{{ j.name || j.label }}
					</el-checkbox>
					
				</el-checkbox-group>
				<el-radio-group
					v-else-if="i.type == 'radio'"
					v-model="formData[i.prop]"
					:disabled="i.disabled ? i.disabled : false"
					
				>
					<el-radio 
						:border="i.border ? i.border : false"
						v-for="j in i.data" :key="j.id || j.value" :label="j.id  || j.value" name="type"
					>
						{{ j.name || j.label }}
					</el-radio>
				</el-radio-group>
				<el-input-number
					v-else-if="i.type == 'number'"
					v-model="formData[i.prop]"
					:placeholder="i.placeholder || '请输入'"
					@input="commonsEmit"
					:disabled="i.disabled ? i.disabled : false"
					:min="i.min ? i.min : 0"
					:max="i.max ? i.max : 100"
					:step="i.step ? i.step : 1">
				</el-input-number>
				<el-tree
					v-else-if="i.type == 'tree'"
					:data="i.data"
					:props="i.props"
					:show-checkbox="i.showCheckbox || true"
				>
				</el-tree>
				<el-cascader
					v-else-if="i.type == 'cascader'"
					:options="i.data"
					:props="i.props"
					:placeholder="i.placeholder || '请选择'"
					@change="commonsEmit"
					:disabled="i.disabled ? i.disabled : false"
					:style="i.style">
				</el-cascader>
				<div class="form-title" v-else-if="i.type == 'title'">
					{{ i.title }}
				</div>
				<slot 
                    :name="i.slotName" 
                    v-else-if="i.type == 'slot'">
                    {{i.slotName}}插槽占位符
                </slot>
			</el-form-item>
		</el-form>
	</div>
</template>
  
<script  setup>
import { set } from '@vueuse/shared'
import { reactive } from 'vue'
defineProps({
	modelValue: {
		type: Object,
		default: false,
	},
	formConfig: {
		type: Array,
		default: false,
	},
	disabled: {
		type: Boolean,
		default: false,
	},
	formOption: {
		type: Object,
		default: false,
	},
	rules: {
		type: Object,
		default: false,
	},
})

const isInit = ref(false)
const { proxy } = getCurrentInstance()
const emit = defineEmits(['update:modelValue'])
const formData = computed(() => {
	return proxy.modelValue	
})
const formDataReset = ref({...proxy.modelValue})
const commonsEmit = (prop,item) => {
	if(item.fn) {
		item.fn(prop)
	}
	emit('update:modelValue', formData.value)
}
const loadInit = () => {
	const v = this
	for (let i = 0; i < proxy.formConfig.length; i++) {
		const element = proxy.formConfig[i]
		if (element.isLoad) {
			commonGetdata(element.isLoad, i)
		}
	}
}
const dateFormatInit = ((itemType) => {
	const formatObj = {
		year:"YYYY",
		month:"YYYY-MM",
		date:"YYYY-MM-DD hh:mm:ss",
		dates:'YYYY-MM-DD',
		datetime:"YYYY-MM-DD hh:mm:ss",
		monthrange:"YYYY-MM-DD hh:mm:ss",
		datetimerange:"YYYY-MM-DD hh:mm:ss",
		daterange:"YYYY-MM-DD hh:mm:ss",
	}

	return formatObj[itemType]
})

//公用递归，保证key，val统一
const commonRecursive = (arr, labelKey, labelVal, childrenName) => {
	for (let i = 0; i < arr.length; i++) {
		console.log(arr[i])
		if(labelKey == 'stringArray'){
			arr[i] = {
				label:arr[i],
				value:arr[i],
				id:arr[i],
				title:arr[i],
			}
		}else{
			arr[i].title = arr[i].label = arr[i][labelKey]
			arr[i].id = arr[i].value = arr[i][labelVal]
		}
		
		if (childrenName) {
			arr[i].children = arr[i][childrenName]
		}
		arr[i].checked = false
		typeof arr[i][labelVal] == String
			? (arr[i].key = arr[i][labelVal])
			: (arr[i].key = JSON.stringify(arr[i][labelVal]))
		if (childrenName) {
			this.commonRecursive(
				arr[i][childrenName],
				labelKey,
				labelVal,
				childrenName
			)
		}
	}
}

//请求form表单所需数据字典
const commonGetdata = (isLoad,i) => {
	proxy[isLoad.method](isLoad.url,isLoad.req).then(message=>{
		console.log(message)
		if (getFormat(isLoad.resUrl, message) == undefined) {
			console.log('请查看isLoad配置是否正确url:' + isLoad.url)
			return
		}
		proxy.formConfig[i].data = getFormat(isLoad.resUrl, message)
		if (isLoad.labelKey) {
			commonRecursive(
				proxy.formConfig[i].data,
				isLoad.labelKey,
				isLoad.labelVal,
				isLoad.childrenName
			)
		}
		console.log(proxy.formConfig[i].data)
	})
}


//根据resurl获取数据
const getFormat = (formatStr, props) => {
	if(!formatStr)  return props
	return formatStr
		.split('.')
		.reduce((total, cur) => (!total ? '' : total[cur]), props)
}

//初始化所有表单
const formDataInit = () => {
	var map = {
		input: '',
		radio: null,
		select: null,
		checkbox: [],
		date: '',
		datetime: '',
		daterange: [],
		datetimerange: [],
		year: null,
		month: null,
		switch: false,
		inputNumber: 0,
		cascader: [],
		Solt: null,
		Transfer: [],
		Upload: { path: null, id: null, name: null },
		password:'',
		treeSelect:'',
	}
	const formDataCopy = { ...formData.value }
	for (let i = 0; i < proxy.formConfig.length; i++) {
		const element = proxy.formConfig[i]
		
		if(formDataCopy[element.prop] || element.type === 'slot') {
			break;
		}
		if(map[element.itemType] != undefined){
			formData.value[element.prop] = map[element.itemType]
		}else{
			formData.value[element.prop] = element.multiple ? [] :  map[element.type]
		}
	}
	emit('update:modelValue', formData.value)
}

const handleSubmit = (onSubmit) => {
	proxy.$refs['byForm'].validate((valid) => {
		if (valid) {
			onSubmit()
		} else {
			ElMessage({
				message: '请检查表单',
				type: 'warning',
			})
		}
	})
}
const byform = ref(null) // 延迟使用，因为还没有返回跟挂载
onMounted(()=>{
	
})
defineExpose({
	handleSubmit,
})
formDataInit()
loadInit()
</script>

<style>

.form-title {
	font-size: 14px;
	font-weight: bold;
	margin-top: 22px;
	color: #333333;
}
.by-form .el-form--inline .el-form-item {
	margin-right: 0px;
	padding-right: 32px;
	box-sizing: border-box;
}

.dn{
	display: none!important;
}


</style>