<template>
	<a-modal :title="title" :open="visible" :confirm-loading="isSaving" :footer="null" @cancel="handleCancel" width="600px">
		<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" :wrapper-col="{ span: 18 }">
			<!-- 标签名称 -->
			<a-form-item label="标签名称" name="label" required>
				<a-input v-model:value="form.label" placeholder="如：正常" allow-clear maxlength="50" show-count />
				<div class="form-tip">用于前端显示的文本</div>
			</a-form-item>

			<!-- 数据值 -->
			<a-form-item label="数据值" name="value" required>
				<a-input v-model:value="form.value" placeholder="如：1" allow-clear />
				<div class="form-tip">实际使用的值，同一字典内必须唯一</div>
			</a-form-item>

			<!-- 颜色标记 -->
			<a-form-item label="颜色标记" name="color">
				<div style="display: flex; align-items: center">
					<input v-model="form.color" type="color" style="width: 60px; height: 32px; cursor: pointer" />
					<a-input v-model:value="form.color" placeholder="#1890ff" allow-clear style="flex: 1; margin-left: 10px" />
				</div>
				<div class="form-tip">用于前端展示的颜色标记</div>
			</a-form-item>

			<!-- 是否默认 -->
			<a-form-item label="默认项" name="is_default">
				<a-switch v-model:checked="isDefaultChecked" checked-children="是" un-checked-children="否" />
				<div class="form-tip" v-if="form.is_default" style="color: #faad14">设置为默认项后，同一字典内的其他默认项将自动取消</div>
			</a-form-item>

			<!-- 排序 -->
			<a-form-item label="排序" name="sort">
				<a-input-number v-model:value="form.sort" :min="0" :max="10000" style="width: 100%" />
			</a-form-item>

			<!-- 状态 -->
			<a-form-item label="状态" name="status">
				<a-switch v-model:checked="statusChecked" checked-children="启用" un-checked-children="禁用" />
			</a-form-item>

			<!-- 描述 -->
			<a-form-item label="描述" name="description">
				<a-textarea v-model:value="form.description" placeholder="请输入描述" :rows="3" maxlength="200" show-count />
			</a-form-item>
		</a-form>

		<!-- 底部按钮 -->
		<div class="dialog-footer">
			<a-space>
				<a-button @click="handleCancel">取消</a-button>
				<a-button type="primary" :loading="isSaving" @click="handleSubmit">保存</a-button>
			</a-space>
		</div>
	</a-modal>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { message } from 'ant-design-vue'
import systemApi from '@/api/system'

// ===== Props =====
const props = defineProps({
	visible: {
		type: Boolean,
		default: false,
	},
	record: {
		type: Object,
		default: null,
	},
	dictionaryId: {
		type: Number,
		default: null,
	},
	itemList: {
		type: Array,
		default: () => [],
	},
})

// ===== Emits =====
const emit = defineEmits(['update:visible', 'success'])

// ===== 状态 =====
const formRef = ref(null)
const isSaving = ref(false)
const isEdit = computed(() => !!props.record?.id)

const title = computed(() => {
	return isEdit.value ? '编辑字典项' : '新增字典项'
})

// ===== 表单数据 =====
const form = ref({
	id: '',
	label: '',
	value: '',
	color: '',
	description: '',
	is_default: false,
	status: true,
	sort: 0,
	dictionary_id: null,
})

// ===== 计算属性：状态开关 =====
const statusChecked = computed({
	get: () => form.value.status === true,
	set: (val) => {
		form.value.status = val ? true : false
	},
})

// ===== 计算属性：默认项开关 =====
const isDefaultChecked = computed({
	get: () => form.value.is_default === true,
	set: (val) => {
		form.value.is_default = val ? true : false
	},
})

// ===== 验证规则 =====
// 数据值唯一性验证
const validateValueUnique = async (rule, value) => {
	if (!value) return Promise.resolve()

	// 检查数据值是否已存在（同一字典内，编辑时排除自己）
	const exists = props.itemList.some((item) => item.value === value && item.id !== props.record?.id)

	if (exists) {
		return Promise.reject('该数据值已存在，请使用其他值')
	}

	return Promise.resolve()
}

const rules = {
	label: [
		{ required: true, message: '请输入标签名称', trigger: 'blur' },
		{
			min: 1,
			max: 50,
			message: '标签名称长度在 1 到 50 个字符',
			trigger: 'blur',
		},
	],
	value: [
		{ required: true, message: '请输入数据值', trigger: 'blur' },
		{ validator: validateValueUnique, trigger: 'blur' },
	],
}

// ===== 方法：重置表单 =====
const resetForm = () => {
	form.value = {
		id: '',
		label: '',
		value: '',
		color: '',
		description: '',
		is_default: false,
		status: true,
		sort: 0,
		dictionary_id: null,
	}
	formRef.value?.clearValidate()
}

// ===== 方法：设置数据（编辑时） =====
const setData = (data) => {
	if (data) {
		form.value = {
			id: data.id || '',
			label: data.label || '',
			value: data.value || '',
			color: data.color || '',
			description: data.description || '',
			is_default: data.is_default || false,
			status: data.status !== undefined ? data.status : true,
			sort: data.sort !== undefined ? data.sort : 0,
			dictionary_id: data.dictionary_id || props.dictionaryId,
		}
	}
}

// ===== 方法：提交表单 =====
const handleSubmit = async () => {
	try {
		// 验证表单
		await formRef.value.validate()

		isSaving.value = true

		const submitData = {
			label: form.value.label,
			value: form.value.value,
			color: form.value.color,
			description: form.value.description,
			is_default: form.value.is_default,
			status: form.value.status,
			sort: form.value.sort,
			dictionary_id: props.dictionaryId,
		}

		let res = {}
		if (isEdit.value) {
			// 编辑
			res = await systemApi.dictionaryItems.edit.put(form.value.id, submitData)
		} else {
			// 新增
			res = await systemApi.dictionaryItems.add.post(submitData)
		}

		if (res.code === 200) {
			message.success(isEdit.value ? '编辑成功' : '新增成功')
			emit('success')
			handleCancel()
		} else {
			message.error(res.message || '操作失败')
		}
	} catch (error) {
		if (error.errorFields) {
			// 表单验证失败
			console.log('表单验证失败:', error)
		} else {
			// API 调用失败
			console.error('提交失败:', error)
			message.error('操作失败')
		}
	} finally {
		isSaving.value = false
	}
}

// ===== 方法：取消 =====
const handleCancel = () => {
	resetForm()
	emit('update:visible', false)
}

// ===== 监听 visible 变化 =====
watch(
	() => props.visible,
	(newVal) => {
		if (newVal) {
			// 打开弹窗时，如果有 record 则设置数据
			if (props.record) {
				setData(props.record)
			} else {
				resetForm()
				// 新增时设置 dictionary_id
				form.value.dictionary_id = props.dictionaryId
			}
		}
	},
	{ immediate: true },
)
</script>

<style scoped lang="scss">
.form-tip {
	font-size: 12px;
	color: #8c8c8c;
	margin-top: 4px;
	line-height: 1.5;
}

.dialog-footer {
	display: flex;
	justify-content: flex-end;
	padding-top: 16px;
	border-top: 1px solid #f0f0f0;
	margin-top: 16px;
}

:deep(.ant-modal-body) {
	max-height: 60vh;
	overflow-y: auto;
}
</style>
