<template>
	<div class="agent-container flex flex-col">
		<div class="agent-header flex align-center space-between">
			<div class="header-title-wrapper">
				<div class="agent-title">{{ props.title }}</div>
				<div class="agent-name">AI Assistant 1.0</div>
			</div>
			<!-- <SvgIcon name="equal" color="#0d0d0d" size="24" /> -->
		</div>
		<div class="agent-body flex-1 flex flex-col">
			<List ref="listRef" :message-list="messageList" @regenerate="handleRegenerate" />
			<Input
				ref="inputRef"
				is-agent-mode
				:generating="isGenerating"
				@send="handleSendMessage"
				@pause="handlePause"
			/>
		</div>
	</div>
</template>

<script setup lang="ts">
	import { ref, reactive, computed, onUnmounted, onMounted, nextTick, watch } from 'vue'
	import List from './List.vue'
	import Input from '../../components/Input.vue'
	import { fetchAgentReply } from '@/api/agent'
	import type { AgentParamsType } from '@/api/agent'
	import { useUserInfoStore, useProjectStore } from '@/stores'
	import { useAgentStore } from '@/stores/agent'

	const userStore = useUserInfoStore()
	const agentStore = useAgentStore()
	const projectStore = useProjectStore()

	const emits = defineEmits(['update:sketchList'])
	const props = withDefaults(
		defineProps<{
			title: string
		}>(),
		{
			title: 'Retro Sofa Sketch'
		}
	)

	const messageList = ref([])

	const listRef = ref()
	const inputRef = ref()
	const isGenerating = ref(false)
	const isPaused = ref(false) // 标记是否为主动暂停
	const params = reactive<AgentParamsType>({
		projectID: projectStore.state.id,
		message: '',
		token: userStore.state.token,
		versionID: '',
		configParams: {
			type: '',
			region: '',
			style: ''
		},
		imageUrlList: []
	})

	const sketchList = ref([])
	watch(
		sketchList,
		(newVal) => {
			emits('update:sketchList', newVal)
		},
		{ deep: true }
	)

	// 每次请求时创建新的 AbortController
	let abort: AbortController

	const createAbortController = () => {
		// 如果已有未完成的中止，先中止它
		if (abort) {
			abort.abort()
		}
		abort = new AbortController()
		return abort
	}

	onUnmounted(() => {
		abort?.abort()
	})

	onMounted(() => {
		// 检查 store 中是否有初始项目数据
		// projectStore.setId('1') // 临时设置项目ID为1，实际应用中应根据上下文动态设置
		const initialData = agentStore.getInitialProjectData
		if (initialData) {
			// 等待页面渲染完成后自动发送初始消息
			params.configParams = {
				type: initialData.type,
				region: initialData.area,
				style: initialData.style,
				temperature: 0.7
			}
			handleSendMessage({
				text: initialData.text,
				images: initialData.images,
				tempImages: initialData.tempImages
			})
			// 更新 configParams

			// 清空初始数据
			agentStore.clearInitialProjectData()
		}
	})

	const handleSendMessage = async (
		message: {
			text: string
			images: Array<{ url: string; name: string }>
			tempImages: any[]
		},
		skipUserMessage = false
	) => {
		isPaused.value = false
		isGenerating.value = true
		params.message = message.text
		params.imageUrlList = message.images || []

		// 如果不是重新生成模式，则添加用户消息到列表
		if (!skipUserMessage) {
			messageList.value.push({
				id: messageList.value.length + 1,
				text: message.text,
				isUser: true,
				imageUrls: message.tempImages
			})
		}

		// Add AI loading message
		const aiMessage = reactive({
			id: messageList.value.length + 1,
			text: '',
			isUser: false,
			loading: true,
			thinking: false,
			thinkingText: '',
			thinkingCollapsed: false,
			streaming: true
		})
		messageList.value.push(aiMessage)

		// 创建新的 AbortController
		const abortController = createAbortController()

		// console.log('token---', params.token, '参数---', params)

		try {
			const urlParams = new URLSearchParams<AgentParamsType>({
				...params,
				configParams: JSON.stringify(params.configParams)
			})
			const BASEURL = import.meta.env.VITE_APP_URL
			const response = await fetch(`${BASEURL}/api/ai-design/chat?${urlParams.toString()}`, {
				method: 'GET',
				signal: abortController.signal
			})

			// 检查响应内容类型，判断是否为流式响应
			const contentType = response.headers.get('content-type') || ''
			const isStreamResponse =
				contentType.includes('text/event-stream') || contentType.includes('stream')

			if (!response.ok) {
				// 非流式错误响应，使用 text() 读取错误信息
				const errorText = await response.text()
				console.error('请求错误:', errorText)
				if (!isPaused.value) {
					aiMessage.text = '发送失败,请重试'
				}
				aiMessage.streaming = false
				aiMessage.loading = false
				isGenerating.value = false
				return
			}

			// 不是流式响应，使用 text()读取错误信息
			if (!isStreamResponse) {
				const text = await response.text()
				try {
					const errorData = JSON.parse(text)
					console.error('非流式响应:', errorData)
				} catch (e) {
					console.error('非流式响应文本:', text)
				}
				if (!isPaused.value) {
					aiMessage.text = '发送失败,请重试'
				}
				aiMessage.streaming = false
				aiMessage.loading = false
				isGenerating.value = false
				return
			}

			// 流式响应处理
			let contentBody = ''
			let buffer = ''
			const reader = response.body?.getReader()
			if (!reader) throw new Error('无法获取流读取器')

			const decoder = new TextDecoder()

			try {
				let flag = true
				while (flag) {
					const { done, value } = await reader.read()
					if (done) {
						// console.log('传输结束 end---', contentBody)
						aiMessage.streaming = false
						aiMessage.loading = false
						isGenerating.value = false
						flag = false
						break
					}

					buffer += decoder.decode(value, { stream: true })
					
					// 优先按空行拆分事件块（SSE标准）
					let events = buffer.split(/\n\n/)
					buffer = events.pop() // 保留不完整块

					for (let event of events) {
						if (!event.trim()) continue

						// 过滤掉 id: 等字段，只取 data:

						let isNodeIdEvent = false
						if (event.startsWith('event:')) {
							isNodeIdEvent = true
							// continue
						}
						console.log('event', event)
						if (event.includes('error')) {
							aiMessage.text = '出现错误,请重试'
							aiMessage.streaming = false
							aiMessage.loading = false
							isGenerating.value = false
							flag = false
							break
						}

						const dataLines = event
							.split(/\n/)
							.filter((line) => line.startsWith('data:'))
							.map((line) => line.replace(/^data:\s*/, '').trim())
						// console.log('dataLInes', dataLines)
						if (isNodeIdEvent) {
							params.versionID = dataLines[0]
							projectStore.setProject({ nodeId: dataLines[0] })
						}

						if (dataLines.length === 0) continue
						const jsonText = dataLines.join('\n')

						try {
							const jsonData = JSON.parse(jsonText)
							// console.log('jsonData', jsonData)

							// 赋值 project_id 和 version_id
							// if (jsonData.project_id) params.projectID = jsonData.project_id
							// if (jsonData.version_id) params.versionID = jsonData.version_id
							if (jsonData.image_url) {
								sketchList.value.push(jsonData.image_url)
							}
							if (
								jsonData.content &&
								jsonData.content.length > 0 &&
								jsonData.type !== 'end'
							) {
								contentBody += jsonData.content
								aiMessage.text = contentBody
								aiMessage.loading = false
							}
							if (jsonData.type === 'end') {
								aiMessage.streaming = false
								aiMessage.loading = false
								isGenerating.value = false
								flag = false
								break
							}
						} catch (e) {
							// 检查是否为纯文本 [DONE]
							if (jsonText.trim() === '[DONE]') {
								console.log('结束-----------------------')
								aiMessage.streaming = false
								aiMessage.loading = false
								isGenerating.value = false
								flag = false
								break
							}
							// JSON 不完整：保留到下一次循环
							if (!jsonText.trim().endsWith('}')) {
								buffer = 'data: ' + jsonText // 重新放回缓存
								continue
							} else {
								console.warn('⚠️ JSON 格式错误，跳过:', jsonText)
							}
						}
					}
				}
			} catch (error) {
				console.error('流式传输错误:', error)
				if (!isPaused.value) {
					aiMessage.text = '发送失败,请重试'
				}
				aiMessage.streaming = false
				aiMessage.loading = false
				isGenerating.value = false
			} finally {
				reader.releaseLock()
			}
		} catch (error) {
			console.error('fetch请求失败:', error)
			if (!isPaused.value) {
				aiMessage.text = '发送失败,请重试'
			}
			aiMessage.streaming = false
			aiMessage.loading = false
			isGenerating.value = false
		}
	}

	const handlePause = () => {
		isPaused.value = true
		isGenerating.value = false
		abort?.abort()
	}

	const handleRegenerate = async (aiMessage: any) => {
		// 找到当前 AI 消息在列表中的索引
		const aiIndex = messageList.value.findIndex((msg) => msg.id === aiMessage.id)
		if (aiIndex === -1) return

		// 找到对应的用户消息（AI 消息前面的最近一条用户消息）
		let userMessage = null
		for (let i = aiIndex - 1; i >= 0; i--) {
			if (messageList.value[i].isUser) {
				userMessage = messageList.value[i]
				break
			}
		}
		if (!userMessage) return

		// 删除当前的 AI 回复消息
		messageList.value.splice(aiIndex, 1)

		// 重新调用 API（跳过用户消息添加，因为用户消息已存在）
		await handleSendMessage(
			{
				text: userMessage.text,
				images: userMessage.images || []
			},
			true
		)
	}

	// 处理对话列表，将连续的 assistant 消息合并为一条
	const processDialogue = (dialogue, startIndex, existingImgList) => {
		if (!dialogue || dialogue.length === 0) return []

		const result = []
		let i = startIndex

		while (i < dialogue.length) {
			const item = dialogue[i]

			if (item.image_url) {
				existingImgList.push(item.image_url)
			}

			if (item.role === 'user') {
				// user 角色直接添加
				result.push({
					...item,
					text: item.content,
					isUser: true,
					id: result.length + 1
				})
				i++
			} else if (item.role === 'assistant') {
				// assistant 角色，拼接直到下一个 user
				let combinedContent = item.content || ''

				// 继续往后找连续的 assistant 消息
				let j = i + 1
				while (j < dialogue.length && dialogue[j].role === 'assistant') {
					if (dialogue[j].image_url) {
						existingImgList.push(dialogue[j].image_url)
					}
					combinedContent += dialogue[j].content || ''
					j++
				}

				result.push({
					...item,
					content: combinedContent,
					text: combinedContent,
					isUser: false,
					id: result.length + 1
				})

				i = j
			} else {
				// 其他角色直接添加
				result.push({
					...item,
					text: item.content,
					isUser: item.role === 'user',
					id: result.length + 1
				})
				i++
			}
		}

		return result
	}

	const setChatInfo = (info) => {
		const initialData = agentStore.getInitialProjectData
		if (isGenerating.value || initialData) return

		const data = info.conversation
		let project = info.project
		if (info.id) {
			project = info
		}

		params.versionID = ''
		sketchList.value = []
		if (project) {
			params.configParams.type = project.type
			params.configParams.region = project.area
			params.configParams.style = project.style
			params.configParams.temperature = project.temperature
		}
		// 如果没有数据，直接返回
		if (!data) {
			messageList.value = []
			return
		}

		const { ancestors, current } = data

		const imgList = []
		const ancestorsList = []
		let ancestorsIdCounter = 1
		if (ancestors) {
			ancestors.forEach((item) => {
				const list = processDialogue(item.dialogue, 0, imgList)
				// 重新设置 id
				list.forEach((el) => {
					el.id = ancestorsIdCounter++
				})
				ancestorsList.push(...list)
			})
		}
		const currentList = processDialogue(current?.dialogue, 0, imgList)
		// 重新设置 id
		currentList.forEach((el, index) => {
			el.id = index + 1 + ancestorsList.length
		})

		// 延迟设置新数据，确保 UI 有时间响应清空操作
		nextTick(() => {
			
			messageList.value = [...ancestorsList, ...currentList]
			params.versionID = current?.id
			sketchList.value = imgList
			console.log('11111111111111',params.versionID);
		})
	}

	defineExpose({
		setChatInfo
	})
</script>

<style lang="less" scoped>
	.c-svg {
		width: initial;
	}
	.agent-container {
		// width: 39%;
		// width: 63.4rem;
		// flex: 1;
		width: 63.4rem;
		margin-right: 2.7rem;
		background-color: #fff;
		border-radius: 2rem;
		box-shadow: 0px 15px 21px 0px #0000000d;

		.agent-header {
			height: 7.4rem;
			border-bottom: 0.1rem solid #c9c9c9;
			padding: 1.4rem 3.4rem 1.4rem 3.1rem;

			.agent-title {
				font-size: 1.8rem;
				margin-bottom: 0.6rem;
			}

			.agent-name {
				font-size: 1.4rem;
			}
		}
		.agent-body {
			padding: 3.2rem;
			overflow: hidden;
			row-gap: 2.4rem;
			.assist-input-wrapper {
				width: 100%;
				height: 14.4rem;
				min-height: 14.4rem !important;
				max-height: 14.4rem !important;
			}
		}
		.input-wrapper {
			height: 14.4rem;
			padding: 0 2rem 3rem;
		}
	}
</style>
