<template>
	<a-form-item v-bind="item.config" :rules="item.rules">
		<slot v-if="item.type == FormItemTypeEnum.CUSTOM" :name="item.config?.name">
			{{ item.config?.name }}
		</slot>
		<component
			:is="typeMap(item.type)"
			v-else-if="
				item.type == FormItemTypeEnum.UPLOAD ||
				item.type == FormItemTypeEnum.SELECT ||
				item.type == FormItemTypeEnum.MENTION
			"
			v-model:[bindPropName(item.type)]="bindValue"
			v-bind="Object.assign({}, $attrs, properties)"
			:disabled="disabled"
		>
			<a-button v-if="item.type == FormItemTypeEnum.UPLOAD">
				<upload-outlined />
			</a-button>
			<template v-else-if="item.type == FormItemTypeEnum.SELECT && properties.options">
				<a-select-option v-for="(option, index2) in properties.options" :key="index2" :value="option.value">
					{{ option.label }}
				</a-select-option>
			</template>
			<template v-else-if="item.type == FormItemTypeEnum.MENTION && properties.options">
				<a-mentions-option v-for="(option, index2) in properties.options" :key="index2" :value="String(option.value)">
					{{ option.label }}
				</a-mentions-option>
			</template>
		</component>
		<component
			:is="typeMap(item.type)"
			v-else
			v-model:[bindPropName(item.type)]="bindValue"
			v-bind="Object.assign({}, $attrs, properties)"
			:disabled="disabled"
		/>
	</a-form-item>
</template>
<script lang="ts" setup>
	import { UploadOutlined } from '@ant-design/icons-vue'
	import { PropType } from 'vue'
	import { FormItem, FormItemTypeEnum, FormValueType } from './form-render-types'
	import XEUtils from 'xe-utils'

	const props = defineProps({
		item: {
			type: Object as PropType<FormItem>,
			required: false,
			default: () => {
				return {}
			},
		},
		disabled: {
			type: Boolean,
			default: () => false,
		},
		value: {
			type: [String, Number, Boolean, Array, Symbol, Object] as PropType<FormValueType>,
			required: false,
			default: () => {
				return undefined
			},
		},
	})
	const { item, value, disabled } = toRefs(props)

	const typeMap = (type: FormItemTypeEnum | string): string => {
		if (type == FormItemTypeEnum.RADIO) {
			return 'a-radio-group'
		}
		if (type == FormItemTypeEnum.CHECKBOX) {
			return 'a-checkbox-group'
		}
		return 'a-' + type
	}

	const properties = computed(() => {
		const p = item.value.properties
		if (item.value.type === FormItemTypeEnum.TRANSFER && !item.value.properties.render) {
			p.render = (item) => item.title
		}
		if (item.value.propertiesTransfer) {
			return item.value.propertiesTransfer(XEUtils.clone(p, true))
		}
		return p
	})

	const bindPropName = (type: string): string => {
		if (type == 'switch') {
			return 'checked'
		}
		if (type == 'transfer') {
			return 'target-keys'
		}
		return 'value'
	}
	const emit = defineEmits<{
		'update:value': [value: FormValueType]
	}>()
	// 双向绑定
	const bindValue = computed({
		get: function (): FormValueType {
			return value?.value ? value.value : undefined
		},
		set: function (value: FormValueType) {
			emit('update:value', value)
		},
	})
</script>
<style lang="css" scoped>
	.ant-input-number,
	.ant-input-number-affix-wrapper,
	.ant-input-number-group-wrapper,
	.ant-picker {
		width: 100% !important;
	}
</style>
