<template>
	<div>
		<a-list item-layout="vertical" :data-source="shownRules">
			<template #header>
				<a-button type="primary" size="small" @click="add">
					<template #icon>
						<icon-font type="icon-plus"></icon-font>
					</template>
					添加
				</a-button>
			</template>
			<template #renderItem="{ item }">
				<a-list-item>
					<template #actions>
						<a-space>
							<span v-if="item.len">
								长度:{{ item.len }}
								<a-divider type="vertical" />
							</span>
							<span v-if="item.max">
								最大:{{ item.max }}
								<a-divider type="vertical" />
							</span>
							<span v-if="item.min">
								最小:{{ item.min }}
								<a-divider type="vertical" />
							</span>
							<span v-if="item.required">
								必填
								<a-divider type="vertical" />
							</span>
							<span v-if="item.whitespace">空格判错</span>
						</a-space>
					</template>
					<a-list-item-meta>
						<template #title>类型: {{ typeTransfer(item.type) }}</template>
						<template #description>
							<span v-if="item.trigger">触发: {{ triggerTransfer(item.trigger) }}</span>
							<br />
							<span v-if="item.enum">枚举值: {{ item.enum }}</span>
							<br />
							验证消息: {{ item.message }}
							<br />
							<span v-if="item.pattern">验证正则: {{ item.pattern }}</span>
						</template>
					</a-list-item-meta>
					<template #extra>
						<a-space>
							<a-button type="primary" size="small" @click="edit(item)">
								<template #icon>
									<icon-font type="icon-edit"></icon-font>
								</template>
							</a-button>
							<a-popconfirm title="确定删除这个校验规则?" @confirm="deleteRule(item)">
								<a-button type="primary" danger size="small">
									<template #icon>
										<icon-font type="icon-delete"></icon-font>
									</template>
								</a-button>
							</a-popconfirm>
						</a-space>
					</template>
				</a-list-item>
			</template>
		</a-list>
		<form-modal
			ref="formModal"
			v-model="rule"
			:form-items="formItems"
			:config="config"
			:title="title"
			:hidden-fields="hiddenFields"
			@ok="hanldOk"
		></form-modal>
	</div>
</template>
<script lang="ts" setup>
	import { FormConfig, FormDataType, FormItem } from '@/components/form-render/form-render-types'
	import { Rule } from 'ant-design-vue/lib/form'
	import { PropType } from 'vue'
	import FormModal from '@/components/form-render/form-modal.vue'
	import XEUtils from 'xe-utils'

	const props = defineProps({
		rules: {
			type: Array as PropType<Rule[]>,
			requried: false,
			default: () => [],
		},
	})
	const { rules } = toRefs(props)

	const shownRules = computed(() => {
		return XEUtils.mapTree(XEUtils.clone(rules.value, true), (item) => {
			return XEUtils.assign(XEUtils.clone(item, true), { uuid: XEUtils.uniqueId() })
		})
	})

	const formItems = reactive<FormItem[]>([
		{
			type: 'radio',
			group: 'form',
			config: {
				autoLink: true,
				hasFeedback: false,
				label: '校验类型',
				name: 'type',
				required: true,
			},
			properties: {
				size: 'small',
				optionType: 'button',
				buttonStyle: 'solid',
				options: [
					{
						label: '字符串',
						value: 'string',
					},
					{
						value: 'date',
						label: '日期',
					},
					{
						value: 'url',
						label: 'URL',
					},
					{
						value: 'hex',
						label: 'HEX',
					},
					{
						value: 'email',
						label: '邮件',
					},
					{
						label: '数字',
						value: 'number',
					},
					{
						value: 'integer',
						label: '整数',
					},
					{
						value: 'float',
						label: '小数',
					},
					{
						value: 'enum',
						label: '枚举',
					},
					{
						value: 'boolean',
						label: '布尔',
					},
					{
						value: 'method',
						label: '方法',
					},
					{
						value: 'regexp',
						label: '正则',
					},
					{
						value: 'array',
						label: '数组',
					},
					{
						value: 'object',
						label: '对象',
					},
				],
			},
			rules: [],
		},
		{
			type: 'checkbox',
			group: 'form',
			config: {
				autoLink: true,
				hasFeedback: false,
				label: '校验触发时机',
				name: 'trigger',
			},
			properties: {
				options: [
					{
						label: '失焦',
						value: 'blur',
					},
					{
						label: '变化',
						value: 'change',
					},
				],
			},
			rules: [],
		},
		{
			type: 'switch',
			group: 'form',
			config: {
				autoLink: true,
				hasFeedback: false,
				label: '是否必填',
				name: 'required',
			},
			properties: {
				size: 'small',
			},
			rules: [],
		},
		{
			type: 'switch',
			group: 'form',
			config: {
				autoLink: true,
				hasFeedback: false,
				label: '空格视为错误',
				name: 'whitespace',
			},
			properties: {
				size: 'small',
			},
			rules: [],
		},
		{
			group: 'form',
			type: 'input',
			config: {
				autoLink: true,
				hasFeedback: false,
				label: '枚举类型',
				name: 'enum',
				required: true,
			},
			properties: {
				size: 'small',
				type: 'text',
				allowClear: true,
				bordered: true,
				showCount: true,
				placeholder: "请输入枚举类型,','分隔",
			},
			rules: [],
		},
		{
			group: 'form',
			type: 'input',
			config: {
				autoLink: true,
				hasFeedback: false,
				label: '校验文案',
				name: 'message',
				required: true,
			},
			properties: {
				size: 'small',
				type: 'text',
				allowClear: true,
				bordered: true,
				showCount: true,
				placeholder: '请输入校验文案',
			},
			rules: [],
		},
		{
			type: 'input-number',
			group: 'form',
			config: {
				autoLink: true,
				hasFeedback: false,
				label: '字段长度',
				name: 'len',
			},
			properties: {
				size: 'small',
				controls: true,
				placeholder: '请输入字段长度',
			},
			rules: [],
		},
		{
			type: 'input-number',
			group: 'form',
			config: {
				autoLink: true,
				hasFeedback: false,
				label: '最大长度',
				name: 'max',
			},
			properties: {
				size: 'small',
				controls: true,
				placeholder: '请输入最大长度',
			},
			rules: [],
		},
		{
			type: 'input-number',
			group: 'form',
			config: {
				autoLink: true,
				hasFeedback: false,
				label: '最小长度',
				name: 'min',
			},
			properties: {
				size: 'small',
				controls: true,
				placeholder: '请输入最小长度',
			},
			rules: [],
		},
		{
			group: 'form',
			type: 'input',
			config: {
				autoLink: true,
				hasFeedback: false,
				label: '检验表达式',
				name: 'pattern',
			},
			properties: {
				size: 'small',
				type: 'text',
				allowClear: true,
				bordered: true,
				showCount: true,
				placeholder: '请输入检验表达式',
			},
			rules: [],
		},
	])

	const typeTransfer = (type: string) => {
		const option = formItems[0].properties.options?.find((item) => item.value === type)
		return option ? option.label : type
	}

	const triggerTransfer = (_trigger: string[]) => {
		return _trigger
			.map((item) => {
				return [
					{
						label: '失焦',
						value: 'blur',
					},
					{
						label: '变化',
						value: 'change',
					},
				].find((o) => o.value === item)?.label
			})
			.join(',')
	}

	const config = reactive<FormConfig>({
		layout: 'horizontal',
		colon: true,
		hideRequiredMark: false,
		labelAlign: 'right',
		labelType: 'responsive',
		scrollToFirstError: false,
		validateOnRuleChange: true,
		labelCol: { span: 6 },
	})
	const rule = ref<FormDataType>({ required: true, whitespace: true, trigger: ['blur'] })

	const title = ref('添加规则')

	const hiddenFields = computed(() => {
		return [...(rule.value.required ? [] : ['whitespace']), ...(rule.value.type === 'enum' ? [] : ['enum'])]
	})
	const formModal = ref<typeof FormModal>()

	const add = () => {
		rule.value = { type: 'string', required: true, whitespace: true, trigger: ['blur'] }
		title.value = '添加规则'
		formModal.value?.open()
	}

	const edit = (_rule: FormDataType) => {
		rule.value = _rule
		title.value = '编辑规则'
		formModal.value?.open()
	}
	const emit = defineEmits<{
		'update:rules': [value: Rule[]]
	}>()

	const deleteRule = (_rule: FormDataType) => {
		emit(
			'update:rules',
			XEUtils.filter(shownRules.value, (item) => item.uuid !== _rule.uuid),
		)
	}

	const hanldOk = (_data: FormDataType) => {
		let d = XEUtils.clone(shownRules.value, true)
		if (_data.uuid) {
			d = XEUtils.map(d, (item: Rule & { uuid: string }) => {
				if (item.uuid === _data.uuid) {
					return _data as unknown as Rule & { uuid: string }
				}
				return item
			})
		} else {
			d.push(_data as unknown as Rule & { uuid: string })
		}
		emit('update:rules', d)
		formModal.value?.close()
	}
</script>
