<template>
	<div class="setting-page">
		<!-- 主内容区域 -->
		<div class="content-wrapper">
			<a-tabs v-model:activeKey="activeGroup" class="config-tabs">
				<template #rightExtra>
					<a-button type="primary" size="small" @click="handleAddConfig"> <PlusOutlined /> 新增配置项 </a-button>
				</template>
				<a-tab-pane v-for="group in groups" :key="group.value" :tab="group.label">
					<a-form :model="formData" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
						<a-form-item :label="config.name" v-for="config in configs[group.value]" :key="config.id" :span="getColumnSpan(config.type)">
							<div class="config-input-wrapper">
								<!-- 不同类型的配置项 -->
								<!-- string/text 类型 -->
								<a-input v-if="['string', 'text'].includes(config.type)" v-model:value="formData[config.key]" :placeholder="config.description" :rows="config.type === 'text' ? 3 : 1" :type="config.type === 'text' ? 'textarea' : 'text'" />

								<!-- number 类型 -->
								<a-input-number v-else-if="config.type === 'number'" v-model:value="formData[config.key]" :placeholder="config.description" :style="{ width: '100%' }" />

								<!-- boolean 类型 -->
								<a-switch v-else-if="config.type === 'boolean'" v-model:checked="formData[config.key]" />

								<!-- select 类型 -->
								<a-select v-else-if="config.type === 'select'" v-model:value="formData[config.key]" :placeholder="config.description" :options="config.options" :style="{ width: '100%' }" allow-clear />

								<!-- radio 类型 -->
								<a-radio-group v-else-if="config.type === 'radio'" v-model:value="formData[config.key]">
									<a-radio v-for="opt in config.options" :key="opt.value" :value="opt.value">
										{{ opt.label }}
									</a-radio>
								</a-radio-group>

								<!-- checkbox 类型 -->
								<a-checkbox-group v-else-if="config.type === 'checkbox'" v-model:value="formData[config.key]">
									<a-checkbox v-for="opt in config.options" :key="opt.value" :value="opt.value">
										{{ opt.label }}
									</a-checkbox>
								</a-checkbox-group>

								<!-- file 类型 -->
								<a-upload v-else-if="config.type === 'file'" v-model:file-list="formData[config.key]" :max-count="1" list-type="picture-card" class="config-upload" :before-upload="() => false">
									<PlusOutlined />
								</a-upload>

								<!-- json 类型 -->
								<div v-else-if="config.type === 'json'" class="json-editor-wrapper">
									<a-textarea v-model:value="jsonStrings[config.key]" placeholder='{"key": "value"}' :rows="4" />
									<div v-if="jsonErrors[config.key]" class="json-error">
										{{ jsonErrors[config.key] }}
									</div>
								</div>

								<!-- 编辑图标 -->
								<a-button type="link" size="small" class="edit-btn" @click="handleEditConfig(config)">
									<EditOutlined />
									编辑
								</a-button>
							</div>
						</a-form-item>
					</a-form>
				</a-tab-pane>
			</a-tabs>
		</div>

		<!-- 底部操作栏 -->
		<div class="footer-bar">
			<a-space>
				<a-button @click="handleReset">重置</a-button>
				<a-button type="primary" :loading="saving" @click="handleSave">
					<SaveOutlined />
					保存配置
				</a-button>
			</a-space>
		</div>
	</div>

	<!-- 保存配置项弹窗 -->
	<SaveConfigDialog v-if="dialog.save" v-model:visible="dialog.save" :record="currentConfig" :default-group="activeGroup" :groups="groups" @success="handleSaveSuccess" />
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { message, Modal } from 'ant-design-vue'
import { PlusOutlined, EditOutlined, SaveOutlined } from '@ant-design/icons-vue'
import systemApi from '@/api/system'
import SaveConfigDialog from './components/SaveConfigDialog.vue'
import { useDictionaryStore } from '@/stores/modules/dictionary'

// ===== 数据定义 =====
const loading = ref(false)
const saving = ref(false)
const activeGroup = ref('')
const groups = ref([])
const configs = ref({})
const formData = reactive({})
const jsonStrings = reactive({})
const jsonErrors = reactive({})

// 是否可以编辑系统配置
const canEditSystem = ref(false)

// 弹窗状态
const dialog = reactive({
	save: false,
})

// 当前编辑的配置项
const currentConfig = ref(null)

// 字典 store
const dictionaryStore = useDictionaryStore()

// ===== 获取列跨度 =====
const getColumnSpan = (type) => {
	if (['text', 'json', 'file'].includes(type)) {
		return 24
	}
	if (['radio', 'checkbox'].includes(type)) {
		return 12
	}
	return 8
}

// ===== 加载配置分组 =====
const loadGroups = async () => {
	try {
		loading.value = true
		const res = await systemApi.config.groups.get()
		if (res.code === 200) {
			const groupList = res.data || []

			// 从字典获取分组标题
			const dictConfig = await dictionaryStore.getDictionary('config_group')

			// 确保 dictConfig 是数组
			const dictItems = Array.isArray(dictConfig) ? dictConfig : []
			const dictMap = dictItems.reduce((acc, item) => {
				acc[item.value] = item.label
				return acc
			}, {})

			// 构建分组列表
			groups.value = groupList.map((group) => ({
				value: group,
				label: dictMap[group] || group,
			}))

			// 设置默认选中第一个分组
			if (groups.value.length > 0 && !activeGroup.value) {
				activeGroup.value = groups.value[0].value
			}
		} else {
			message.error(res.message || '加载配置分组失败')
		}
	} catch (error) {
		console.error('加载配置分组失败:', error)
		message.error('加载配置分组失败')
	} finally {
		loading.value = false
	}
}

// ===== 加载配置项 =====
const loadConfigs = async () => {
	try {
		loading.value = true
		const res = await systemApi.config.all.get()
		if (res.code === 200) {
			const configList = res.data || []

			// 按分组整理配置项
			configs.value = configList.reduce((acc, config) => {
				if (!acc[config.group]) {
					acc[config.group] = []
				}
				acc[config.group].push(config)
				return acc
			}, {})

			// 初始化表单数据
			configList.forEach((config) => {
				const value = config.value ?? config.default_value ?? ''

				// 根据类型转换值
				if (config.type === 'boolean') {
					formData[config.key] = value === true || value === '1'
				} else if (config.type === 'checkbox') {
					formData[config.key] = typeof value === 'string' ? JSON.parse(value) : value
				} else if (config.type === 'json') {
					jsonStrings[config.key] = typeof value === 'string' ? value : JSON.stringify(value)
					delete jsonErrors[config.key]
				} else if (config.type === 'file') {
					// file 类型：将字符串转换为文件列表格式
					if (typeof value === 'string' && value) {
						try {
							const fileInfo = JSON.parse(value)
							formData[config.key] = Array.isArray(fileInfo) ? fileInfo : [fileInfo]
						} catch {
							formData[config.key] = []
						}
					} else {
						formData[config.key] = []
					}
				} else {
					formData[config.key] = value
				}
			})
		} else {
			message.error(res.message || '加载配置项失败')
		}
	} catch (error) {
		console.error('加载配置项失败:', error)
		message.error('加载配置项失败')
	} finally {
		loading.value = false
	}
}

// ===== 验证 JSON 格式 =====
const validateJson = (key) => {
	const jsonStr = jsonStrings[key]
	if (!jsonStr || jsonStr.trim() === '') {
		delete jsonErrors[key]
		return true
	}

	try {
		const parsed = JSON.parse(jsonStr)
		formData[key] = parsed
		delete jsonErrors[key]
		return true
	} catch (e) {
		jsonErrors[key] = 'JSON 格式错误: ' + e.message
		return false
	}
}

// ===== 保存配置 =====
const handleSave = async () => {
	// 验证 JSON 类型
	const hasJsonError = Object.keys(jsonErrors).some((key) => jsonErrors[key])
	if (hasJsonError) {
		message.error('请先修正 JSON 格式错误')
		return
	}

	// 验证所有 JSON 字段
	const allJsonValid = Object.keys(jsonStrings).every((key) => validateJson(key))
	if (!allJsonValid) {
		message.error('JSON 格式错误')
		return
	}

	// 检查是否有需要保存的配置
	const configList = Object.values(configs.value).flat()
	if (configList.length === 0) {
		message.warning('暂无配置项可保存')
		return
	}

	// 构建更新数据
	const updates = []
	Object.keys(formData).forEach((key) => {
		const config = configList.find((c) => c.key === key)
		if (config) {
			let value = formData[key]
			// 转换 checkbox 类型为数组字符串
			if (config.type === 'checkbox') {
				value = JSON.stringify(value)
			}
			// 转换 file 类型为 JSON 字符串
			else if (config.type === 'file' && Array.isArray(value) && value.length > 0) {
				value = JSON.stringify(value)
			}
			updates.push({ id: config.id, value })
		}
	})

	if (updates.length === 0) {
		message.warning('暂无配置项需要保存')
		return
	}

	// 批量更新
	try {
		saving.value = true
		const promises = updates.map((update) => systemApi.config.edit.put(update.id, { value: update.value }))
		await Promise.all(promises)
		message.success('保存成功')
		// 重新加载配置
		await loadConfigs()
	} catch (error) {
		console.error('保存配置失败:', error)
		message.error('保存配置失败')
	} finally {
		saving.value = false
	}
}

// ===== 重置配置 =====
const handleReset = () => {
	Modal.confirm({
		title: '确认重置',
		content: '确定要重置当前分组的所有配置项吗？',
		okText: '确定',
		cancelText: '取消',
		onOk: async () => {
			// 重新加载配置
			await loadConfigs()
			message.success('已重置')
		},
	})
}

// ===== 编辑配置项 =====
const handleEditConfig = (config) => {
	currentConfig.value = config
	dialog.save = true
}

// ===== 新增配置项 =====
const handleAddConfig = () => {
	currentConfig.value = null
	dialog.save = true
}

// ===== 保存成功回调 =====
const handleSaveSuccess = () => {
	dialog.save = false
	// 刷新分组列表
	loadGroups()
	// 刷新配置项
	loadConfigs()
}

// ===== 生命周期 =====
onMounted(async () => {
	// 先加载字典缓存
	await dictionaryStore.getDictionary('config_group')
	// 加载配置分组
	await loadGroups()
	// 加载配置项
	await loadConfigs()
})
</script>

<style scoped lang="scss">
.setting-page {
	display: flex;
	flex-direction: column;
	height: 100%;
	padding: 0;
	background: #f5f5f5;

	.content-wrapper {
		flex: 1;
		overflow: hidden;
		display: flex;
		background: #fff;
		margin: 16px;
		border-radius: 8px;
		box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);

		.config-tabs {
			width: 100%;
			display: flex;
			flex-direction: column;

			:deep(.ant-tabs-nav) {
				margin-bottom: 0;
				padding: 0 8px;
				background: #fafafa;
				border-bottom: 1px solid #f0f0f0;
				border-radius: 8px 8px 0 0;
			}

			:deep(.ant-tabs-tab) {
				padding: 12px 20px;
				font-size: 14px;
				font-weight: 500;
				transition: all 0.3s;

				&:hover {
					color: #1890ff;
				}

				&.ant-tabs-tab-active {
					color: #1890ff;
					background: #fff;
					border-top: 2px solid #1890ff;
				}
			}

			:deep(.ant-tabs-ink-bar) {
				display: none;
			}

			:deep(.ant-tabs-content) {
				flex: 1;
				overflow: hidden;
				display: flex;
			}

			:deep(.ant-tabs-tabpane) {
				height: 100%;
				overflow: hidden;
				display: flex;
			}

			:deep(.ant-tabs-content-holder) {
				flex: 1;
				overflow-y: auto;
				padding: 16px;
			}

			:deep(.ant-form) {
				width: 100%;
			}
		}

		.config-content {
			padding: 24px;
		}
	}

	.footer-bar {
		padding: 16px 24px;
		border-top: 1px solid #f0f0f0;
		background: #fff;
		display: flex;
		justify-content: flex-end;
		align-items: center;
		box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.04);
		z-index: 10;

		.ant-btn {
			border-radius: 6px;
			height: 36px;
			padding: 0 24px;
			font-weight: 500;
		}
	}
}

.config-input-wrapper {
	display: flex;
	align-items: center;
	justify-items: center;

	.edit-btn {
		padding: 4px 8px;
		font-size: 12px;
		background: rgba(255, 255, 255, 0.95);
		border-radius: 4px;
	}
}
</style>
