<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
import SchemaTreeNode, { type SchemaNode } from './SchemaTreeNode.vue'

interface SchemaData {
	type: 'object'
	properties: Record<string, any>
	required?: string[]
	additionalProperties?: boolean
}

const props = defineProps<{
	modelValue: SchemaData | null
	visible: boolean
}>()

const emit = defineEmits<{
	(e: 'update:modelValue', value: SchemaData): void
	(e: 'close'): void
}>()

const activeTab = ref<'visual' | 'json'>('visual')

const dialogVisible = computed({
	get: () => props.visible,
	set: (value) => {
		if (!value) close()
	}
})

// 根节点模型
const rootNode = ref<SchemaNode>({
	name: 'root',
	type: 'object',
	description: '',
	enumValues: '',
	required: false,
	children: []
})

const jsonSchema = ref<string>('')

// --- 核心转换逻辑  ---

const getArrayItemType = (type: string) => type.match(/^array\[(.*)\]$/)?.[1] || 'string'

const parseEnumValues = (value?: string) =>
	(value || '')
		.split(',')
		.map((v) => v.trim())
		.filter(Boolean)

const parseSchemaToNode = (schema: any): SchemaNode[] => {
	if (!schema || !schema.properties) return []

	const nodes: SchemaNode[] = []
	const requiredFields = new Set(schema.required || [])

	Object.keys(schema.properties).forEach((key) => {
		const prop = schema.properties[key]

		// 确定显示类型字符串
		let displayType = prop.type || 'string'
		if (prop.type === 'array' && prop.items) {
			const itemType = prop.items.type || 'string'
			displayType = `array[${itemType}]`
		}

		const node: SchemaNode = {
			name: key,
			type: displayType,
			description: prop.description || '',
			enumValues: Array.isArray(prop.enum) ? prop.enum.join(', ') : '',
			required: requiredFields.has(key),
			children: []
		}

		// 处理子节点
		if (prop.type === 'object' && prop.properties) {
			node.children = parseSchemaToNode(prop)
		} else if (prop.type === 'array' && prop.items) {
			const itemSchema = prop.items
			const itemType = itemSchema.type || 'string'

			// 关键修改：如果数组项是 object，不创建中间 item 节点，直接解析属性到 children
			if (itemType === 'object') {
				node.children = itemSchema.properties ? parseSchemaToNode(itemSchema) : []
			}
			// 如果数组项是简单类型或其他，保留原有的 item 节点结构
			else {
				const itemNode: SchemaNode = {
					name: 'item',
					type: itemType,
					description: itemSchema.description || '',
					enumValues: Array.isArray(itemSchema.enum) ? itemSchema.enum.join(', ') : '',
					required: false,
					children: []
				}

				// 如果 item 是 object 但没有 properties (空对象)，或者 item 是其他复杂类型
				if (itemType === 'object' && itemSchema.properties) {
					itemNode.children = parseSchemaToNode(itemSchema)
				}

				node.children = [itemNode]
			}
		}

		nodes.push(node)
	})
	return nodes
}

const buildSchemaFromNode = (nodes: SchemaNode[]) => {
	const properties: any = {}
	const required: string[] = []

	nodes.forEach((node) => {
		if (!node.name || !node.name.trim()) return

		const prop: any = {
			description: node.description || undefined
		}

		// 处理枚举 (仅针对非数组的基本类型)
		if (!node.type.startsWith('array[') && node.enumValues && node.enumValues.trim()) {
			const enums = parseEnumValues(node.enumValues)
			if (enums.length > 0) {
				prop.enum = enums
			}
		}

		// 处理 Object 类型
		if (node.type === 'object') {
			const nested = buildSchemaFromNode(node.children || [])
			prop.type = 'object'
			prop.properties = nested.properties
			prop.required = nested.required
			prop.additionalProperties = false
		}
		// 处理 Array 类型
		else if (node.type.startsWith('array[')) {
			const itemType = getArrayItemType(node.type)
			const itemSchema: any = {
				type: itemType
			}

			prop.type = 'array'

			// 关键修改：如果是 array[object]，children 直接就是 object 的属性列表
			if (itemType === 'object') {
				const nested = buildSchemaFromNode(node.children || [])
				itemSchema.properties = nested.properties
				itemSchema.required = nested.required
				itemSchema.additionalProperties = false
			}
			// 如果是 array[string/number...]，children[0] 是 item 节点
			else {
				if (node.children && node.children.length > 0) {
					const itemNode = node.children[0]

					// 设置 item 的描述
					if (itemNode.description) {
						itemSchema.description = itemNode.description
					}

					// 设置 item 的枚举
					if (itemNode.enumValues && itemNode.enumValues.trim()) {
						const enums = parseEnumValues(itemNode.enumValues)
						if (enums.length > 0) {
							itemSchema.enum = enums
						}
					}
				}
			}

			prop.items = itemSchema
		}
		// 处理基本类型
		else {
			prop.type = node.type
		}

		properties[node.name] = prop

		if (node.required) {
			required.push(node.name)
		}
	})

	return { properties, required }
}

// --- 监听与初始化 ---

const syncFromModelValue = (value: SchemaData | null) => {
	if (value) {
		rootNode.value.children = parseSchemaToNode(value)
		jsonSchema.value = JSON.stringify(value, null, 2)
		return
	}

	rootNode.value.children = []
	jsonSchema.value = ''
}

watch(
	() => props.modelValue,
	(newVal) => {
		syncFromModelValue(newVal)
	},
	{ immediate: true }
)

watch(
	() => props.visible,
	(visible) => {
		if (visible) {
			activeTab.value = 'visual'
			syncFromModelValue(props.modelValue)
		}
	}
)

// 保存
const save = () => {
	// 在保存前再次检查是否有重复名称
	const checkDuplicates = (nodes: SchemaNode[]): boolean => {
		const names = new Set<string>()
		for (const node of nodes) {
			if (node.name && names.has(node.name)) return true
			names.add(node.name)
			if (node.children && checkDuplicates(node.children)) return true
		}
		return false
	}

	if (checkDuplicates(rootNode.value.children || [])) {
		ElMessage.error('存在重复的字段名，请修正后保存')
		return
	}

	if (activeTab.value === 'visual') {
		const { properties, required } = buildSchemaFromNode(rootNode.value.children || [])

		const schema: SchemaData = {
			type: 'object',
			properties,
			required,
			additionalProperties: false
		}

		jsonSchema.value = JSON.stringify(schema, null, 2)
		emit('update:modelValue', schema)
		ElMessage.success('保存成功')
	} else {
		try {
			const parsed = JSON.parse(jsonSchema.value)
			if (parsed.type !== 'object' || typeof parsed.properties !== 'object') {
				throw new Error('Schema 根节点必须是 object 且包含 properties')
			}
			const normalized: SchemaData = {
				type: 'object',
				properties: parsed.properties || {},
				required: Array.isArray(parsed.required) ? parsed.required : [],
				additionalProperties: Boolean(parsed.additionalProperties)
			}
			jsonSchema.value = JSON.stringify(normalized, null, 2)
			emit('update:modelValue', normalized)
			ElMessage.success('保存成功')
		} catch (e: any) {
			ElMessage.error('JSON 格式错误: ' + e.message)
		}
	}
}

const clearConfig = () => {
	rootNode.value.children = []
	const emptySchema = {
		type: 'object',
		properties: {},
		required: [],
		additionalProperties: false
	}
	jsonSchema.value = JSON.stringify(emptySchema, null, 2)
	emit('update:modelValue', emptySchema)
}

const close = () => {
	emit('close')
}
</script>

<template>
	<el-dialog
		v-model="dialogVisible"
		title="结构化输出 Schema 配置"
		width="900px"
		:close-on-click-modal="false"
		append-to-body
		@close="close"
	>
		<div class="tab-header">
			<el-segmented
				v-model="activeTab"
				:options="[
					{ label: 'Visual Editor', value: 'visual' },
					{ label: 'JSON Schema', value: 'json' }
				]"
			/>
		</div>

		<!-- Visual Editor -->
		<div v-if="activeTab === 'visual'" class="visual-editor">
			<div class="schema-root-container">
				<div class="root-label">
					<span class="icon">📦</span>
					<span class="text">Root Object (structured_output)</span>
				</div>

				<div class="tree-content">
					<!-- 递归渲染根节点的子项，传入 siblings 用于校验 -->
					<SchemaTreeNode
						v-for="(child, index) in rootNode.children"
						:key="index"
						v-model="rootNode.children[index]"
						:index="index"
						:siblings="rootNode.children"
						@remove="rootNode.children.splice(index, 1)"
					/>

					<div v-if="!rootNode.children || rootNode.children.length === 0" class="empty-state">
						<el-empty description="暂无字段，请添加顶级字段" :image-size="60" />
					</div>

					<el-button
						type="primary"
						plain
						icon="Plus"
						@click="
							rootNode.children?.push({
								name: '',
								type: 'string',
								description: '',
								enumValues: '',
								required: false,
								children: []
							})
						"
						class="add-root-btn"
					>
						添加顶级字段
					</el-button>
				</div>
			</div>
		</div>

		<!-- JSON Editor -->
		<div v-else class="json-editor">
			<CodeEditor v-model="jsonSchema" language="json" :height="480" />
		</div>

		<template #footer>
			<el-button @click="clearConfig">清空</el-button>
			<el-button @click="close">取消</el-button>
			<el-button type="primary" @click="save">保存配置</el-button>
		</template>
	</el-dialog>
</template>

<style scoped>
.tab-header {
	margin-bottom: 16px;
	display: flex;
	justify-content: center;
}

.visual-editor {
	max-height: 60vh;
	overflow-y: auto;
	padding: 4px;
}

.schema-root-container {
	background: #f9fafc;
	border: 1px solid #e4e7ed;
	border-radius: 8px;
	padding: 20px;
}

.root-label {
	font-weight: 600;
	color: #303133;
	margin-bottom: 20px;
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 14px;
}

.tree-content {
	padding-left: 0;
}

.add-root-btn {
	width: 100%;
	margin-top: 16px;
	border-style: dashed;
}

.json-editor {
	height: 500px;
	border: 1px solid #e4e7ed;
	border-radius: 4px;
}

.empty-state {
	padding: 20px 0;
}
</style>
