<template>
	<a-form :model="form" :rules="rules" ref="formRef" :label-col="{ span: 5 }" :wrapper-col="{ span: 18 }">
		<!-- 第一行：权限名称和类型 -->
		<a-row :gutter="16">
			<a-col :span="12">
				<a-form-item label="权限名称" name="title" required>
					<a-input v-model:value="form.title" placeholder="如：用户管理" allow-clear :maxlength="50" show-count />
				</a-form-item>
			</a-col>
			<a-col :span="12">
				<a-form-item label="权限类型" name="type" required :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
					<a-radio-group v-model:value="form.type" button-style="solid" @change="handleTypeChange">
						<a-radio-button value="menu">菜单</a-radio-button>
						<a-radio-button value="api">接口</a-radio-button>
						<a-radio-button value="button">按钮</a-radio-button>
						<a-radio-button value="url">链接</a-radio-button>
					</a-radio-group>
				</a-form-item>
			</a-col>
		</a-row>

		<!-- 第二行：上级权限和权限编码 -->
		<a-row :gutter="16">
			<a-col :span="12">
				<a-form-item label="上级权限" name="parent_id">
					<a-tree-select v-model:value="form.parent_id" :tree-data="menuOptions" :field-names="menuFieldNames" :tree-default-expand-all="false" show-icon placeholder="顶级权限" allow-clear tree-node-filter-prop="title" :disabled="!!menuId" />
				</a-form-item>
			</a-col>
			<a-col :span="12">
				<a-form-item label="权限编码" name="name" required>
					<a-input v-model:value="form.name" placeholder="如：system.users.index" allow-clear />
					<div class="form-tip">格式：模块.功能.操作，系统唯一标识，用于权限验证</div>
				</a-form-item>
			</a-col>
		</a-row>

		<!-- 第三行：路由地址和组件路径（菜单类型才显示） -->
		<a-row v-if="form.type === 'menu'" :gutter="16">
			<a-col :span="12">
				<a-form-item label="路由地址" name="path" :required="isLeafNode">
					<a-input v-model:value="form.path" placeholder="/system/users" allow-clear />
					<div class="form-tip">前端路由路径，如 /system/users</div>
				</a-form-item>
			</a-col>
			<a-col :span="12">
				<a-form-item label="组件路径" name="component" :required="isLeafNode">
					<a-input v-model:value="form.component" placeholder="system/users/index" allow-clear>
						<template #addonBefore>pages/</template>
					</a-input>
					<div class="form-tip" v-if="!isLeafNode">父级菜单或包含子菜单时不需要填写</div>
					<div class="form-tip" v-else>最后一级菜单必须填写，如 system/users/index</div>
				</a-form-item>
			</a-col>
		</a-row>

		<!-- API 类型显示路由名称 -->
		<a-row v-if="form.type === 'api'" :gutter="16">
			<a-col :span="12">
				<a-form-item label="API路由" name="path" required>
					<a-input v-model:value="form.path" placeholder="如：users.index" allow-clear />
					<div class="form-tip">后端 API 路由名称，用于接口权限验证</div>
				</a-form-item>
			</a-col>
		</a-row>

		<!-- 链接类型显示 URL -->
		<a-row v-if="form.type === 'url'" :gutter="16">
			<a-col :span="12">
				<a-form-item label="链接地址" name="path" required>
					<a-input v-model:value="form.path" placeholder="https://example.com" allow-clear />
					<div class="form-tip">外部链接地址</div>
				</a-form-item>
			</a-col>
		</a-row>

		<!-- 第四行：菜单图标和排序（菜单类型才显示） -->
		<a-row v-if="form.type === 'menu'" :gutter="16">
			<a-col :span="12">
				<a-form-item label="菜单图标" name="icon">
					<sc-icon-picker v-model:value="form.icon" placeholder="请选择图标" />
				</a-form-item>
			</a-col>
			<a-col :span="12">
				<a-form-item label="排序" name="sort">
					<a-input-number v-model:value="form.sort" :min="0" :max="10000" style="width: 100%" />
					<div class="form-tip">数值越小越靠前</div>
				</a-form-item>
			</a-col>
		</a-row>

		<!-- 分隔线 -->
		<a-divider />

		<!-- 选项设置区域（菜单类型才显示） -->
		<div v-if="form.type === 'menu'" class="options-section">
			<h4>选项设置</h4>
			<a-row :gutter="16">
				<a-col :span="12">
					<a-form-item label="显示选项" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
						<a-checkbox v-model:checked="form.hidden">隐藏菜单</a-checkbox>
						<a-checkbox v-model:checked="form.hiddenBreadcrumb">隐藏面包屑</a-checkbox>
						<a-checkbox v-model:checked="form.affix">固定标签页</a-checkbox>
					</a-form-item>
				</a-col>
				<a-col :span="12">
					<a-form-item label="页面缓存" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
						<a-switch v-model:checked="form.keepAlive" checked-children="启用" un-checked-children="禁用" />
						<div class="form-tip">启用后页面会被缓存，切换回来时保留状态</div>
					</a-form-item>
				</a-col>
			</a-row>
		</div>

		<!-- 外链打开方式（链接类型才显示） -->
		<div v-if="form.type === 'url'" class="options-section">
			<h4>外链设置</h4>
			<a-row :gutter="16">
				<a-col :span="12">
					<a-form-item label="打开方式" name="target">
						<a-radio-group v-model:value="form.target">
							<a-radio value="_self">当前窗口</a-radio>
							<a-radio value="_blank">新窗口</a-radio>
						</a-radio-group>
					</a-form-item>
				</a-col>
			</a-row>
		</div>

		<!-- 分隔线 -->
		<a-divider />

		<!-- 状态 -->
		<a-row :gutter="16">
			<a-col :span="12">
				<a-form-item label="启用状态" name="status" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
					<a-switch v-model:checked="statusChecked" checked-children="启用" un-checked-children="禁用" />
					<div class="form-tip">禁用后该权限将不生效</div>
				</a-form-item>
			</a-col>
		</a-row>

		<!-- 操作按钮 -->
		<a-form-item :wrapper-col="{ span: 18, offset: 5 }" style="margin-top: 32px">
			<a-space>
				<a-button type="primary" @click="handleSave" :loading="loading" size="large">
					<template #icon><CheckOutlined /></template>
					保存
				</a-button>
				<a-button @click="$emit('cancel')" size="large">
					<template #icon><CloseOutlined /></template>
					取消
				</a-button>
			</a-space>
		</a-form-item>
	</a-form>
</template>

<script setup>
import { ref, reactive, watch, computed, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { CheckOutlined, CloseOutlined } from '@ant-design/icons-vue'
import authApi from '@/api/auth'
import scIconPicker from '@/components/scIconPicker/index.vue'

defineOptions({
	name: 'PermissionSaveForm',
})

const props = defineProps({
	menu: { type: [Object, Array], default: () => [] },
	menuId: { type: [Number, String], default: null },
	parentId: { type: [Number, String], default: null },
})

const emit = defineEmits(['success', 'cancel'])

// 表单数据
const form = reactive({
	id: '',
	parent_id: 0,
	name: '',
	title: '',
	path: '',
	component: '',
	icon: '',
	sort: 0,
	type: 'menu',
	status: 1,
	target: '_self',
	// meta 字段内容
	hidden: false,
	hiddenBreadcrumb: false,
	keepAlive: false,
	affix: false,
})

// 表单引用
const formRef = ref()
const loading = ref(false)

// 验证规则
const rules = {
	title: [
		{ required: true, message: '请输入权限名称', trigger: 'blur' },
		{ max: 50, message: '权限名称不能超过50个字符', trigger: 'blur' },
	],
	name: [
		{ required: true, message: '请输入权限编码', trigger: 'blur' },
		{
			pattern: /^[a-zA-Z][a-zA-Z0-9_.]*$/,
			message: '权限编码格式不正确，格式：模块.功能.操作',
			trigger: 'blur',
		},
	],
	type: [{ required: true, message: '请选择权限类型', trigger: 'change' }],
	path: (rule, value) => {
		// 根据类型动态验证
		if (form.type === 'menu' || form.type === 'api' || form.type === 'url') {
			if (!value || !value.trim()) {
				return Promise.reject('请输入' + getPathLabel(form.type))
			}
		}
		return Promise.resolve()
	},
	component: (rule, value) => {
		// 仅在菜单类型且为叶子节点时验证
		if (form.type === 'menu' && isLeafNode.value) {
			if (!value || !value.trim()) {
				return Promise.reject('请输入组件路径')
			}
		}
		return Promise.resolve()
	},
}

// 路径字段标签
const getPathLabel = (type) => {
	const labelMap = {
		menu: '路由地址',
		api: 'API路由',
		url: '链接地址',
	}
	return labelMap[type] || '路径'
}

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

// 判断是否为叶子节点（没有子节点的节点）
const isLeafNode = computed(() => {
	// 这里需要根据当前节点是否有子节点来判断
	// 暂时返回 false，需要根据实际数据判断
	return !hasChildren.value
})

// 判断是否有子节点
const hasChildren = computed(() => {
	if (!form.id || !props.menu) return false
	const node = findMenuNode(props.menu, form.id)
	return node && node.children && node.children.length > 0
})

// 菜单选项
const menuOptions = ref([])
const menuFieldNames = {
	value: 'id',
	label: 'title',
	children: 'children',
}

// 筛单化菜单树，排除自己和子节点
const treeToMap = (tree, excludeId = null) => {
	const map = []
	tree.forEach((item) => {
		if (item.id === excludeId) return // 排除自己
		const obj = {
			id: item.id,
			parent_id: item.parent_id,
			title: item.title,
			children: item.children && item.children.length > 0 ? treeToMap(item.children, excludeId) : null,
		}
		map.push(obj)
	})
	return map
}

// 查找权限节点
const findMenuNode = (tree, id) => {
	for (const node of tree) {
		if (node.id === id) {
			return node
		}
		if (node.children && node.children.length > 0) {
			const found = findMenuNode(node.children, id)
			if (found) return found
		}
	}
	return null
}

// 监听菜单树变化
watch(
	() => props.menu,
	(newVal) => {
		if (newVal) {
			// 排除当前编辑的节点，避免选择自己作为父节点
			menuOptions.value = treeToMap(newVal, props.menuId)
		}
	},
	{ deep: true, immediate: true },
)

// 监听 menuId 变化，从菜单树中查找并赋值
watch(
	() => props.menuId,
	(newVal) => {
		if (newVal && props.menu && props.menu.length > 0) {
			const menuNode = findMenuNode(props.menu, newVal)
			if (menuNode) {
				setData(menuNode, props.parentId)
			}
		} else if (!newVal) {
			// 清空表单
			resetForm()
		}
	},
)

// 类型切换处理
const handleTypeChange = () => {
	// 类型切换时清空一些字段
	form.path = ''
	form.component = ''
	form.icon = ''
	// 非菜单类型时清空meta相关字段
	if (form.type !== 'menu') {
		form.hidden = false
		form.hiddenBreadcrumb = false
		form.keepAlive = false
		form.affix = false
	}
	// 非链接类型时重置target
	if (form.type !== 'url') {
		form.target = '_self'
	}
}

// 重置表单
const resetForm = () => {
	Object.assign(form, {
		id: '',
		parent_id: props.parentId || 0,
		name: '',
		title: '',
		path: '',
		component: '',
		icon: '',
		sort: 0,
		type: 'menu',
		status: 1,
		target: '_self',
		hidden: false,
		hiddenBreadcrumb: false,
		keepAlive: false,
		affix: false,
	})
}

// 加载权限详情
const loadMenuDetail = async (id) => {
	try {
		const res = await authApi.permission.detail.get(id)
		if (res.code === 200 && res.data) {
			setData(res.data, props.parentId)
		}
	} catch (error) {
		console.error('加载权限详情失败:', error)
	}
}

// 保存
const handleSave = async () => {
	try {
		await formRef.value.validate()
		loading.value = true

		// 构建提交数据
		const submitData = {
			id: form.id || undefined,
			parent_id: form.parent_id || 0,
			name: form.name,
			title: form.title,
			path: form.path,
			component: form.component,
			icon: form.icon,
			sort: form.sort,
			type: form.type,
			status: form.status,
			target: form.target,
			meta: null,
		}

		// 仅菜单类型才有meta字段
		if (form.type === 'menu') {
			submitData.meta = {
				hidden: form.hidden,
				hiddenBreadcrumb: form.hiddenBreadcrumb,
				keepAlive: form.keepAlive,
				affix: form.affix,
			}
		}

		// 根据类型处理空值
		if (form.type === 'button' || form.type === 'api') {
			submitData.component = ''
			submitData.icon = ''
		}
		if (form.type === 'button') {
			submitData.path = ''
		}
		if (form.type === 'api' || form.type === 'button' || form.type === 'url') {
			submitData.meta = null
		}

		let res = {}
		if (form.id) {
			res = await authApi.permission.edit.put(form.id, submitData)
		} else {
			res = await authApi.permission.add.post(submitData)
		}

		loading.value = false
		if (res.code === 200) {
			message.success('保存成功')
			emit('success')
		} else {
			message.error(res.message || '保存失败')
		}
	} catch (error) {
		console.error('表单验证失败', error)
		loading.value = false
		if (error?.errorFields) {
			// 表单验证失败
			return
		}
		message.error('保存失败')
	}
}

// 表单注入数据
const setData = (data, pid) => {
	form.id = data.id || ''
	form.parent_id = data.parent_id !== undefined ? data.parent_id : pid || 0
	form.name = data.name || ''
	form.title = data.title || ''
	form.path = data.path || ''
	form.component = data.component || ''
	form.icon = data.icon || ''
	form.sort = data.sort || 0
	form.type = data.type || 'menu'
	form.status = data.status !== undefined ? data.status : 1
	form.target = data.target || '_self'

	// 解析 meta 字段
	const meta = data.meta && typeof data.meta === 'string' ? JSON.parse(data.meta) : data.meta || {}
	form.hidden = meta.hidden || false
	form.hiddenBreadcrumb = meta.hiddenBreadcrumb || false
	form.keepAlive = meta.keepAlive || false
	form.affix = meta.affix || false
}

// 初始化
onMounted(() => {
	if (props.menuId) {
		loadMenuDetail(props.menuId)
	} else if (props.parentId) {
		form.parent_id = props.parentId
	}
})

// 清空表单验证
const clearValidate = () => {
	formRef.value?.clearValidate()
}

// 暴露方法给父组件
defineExpose({
	setData,
	clearValidate,
	resetForm,
})
</script>

<style scoped lang="scss">
.save-form {
	padding: 24px;
	background: #fff;

	.form-tip {
		font-size: 12px;
		color: #8c8c8c;
		margin-top: 4px;
		line-height: 1.5;
	}

	.options-section {
		margin-top: 16px;

		h4 {
			font-size: 16px;
			font-weight: 500;
			color: #262626;
			margin-bottom: 24px;
		}
	}

	.ant-divider {
		margin: 32px 0;
	}

	.ant-form-item {
		margin-bottom: 24px;
	}

	.ant-input-number {
		width: 100%;
	}
}
</style>
