<template>
	<div
		ref="containerRef"
		class="preview-container flex"
		v-loading="urlLoading"
		:class="type === 'sketch' ? 'sketch-preview' : 'report-preview'"
	>
		<template v-if="type === 'sketch'">
			<div
				class="sketch-item flex flex-center"
				v-for="(item, index) in combineSketchList"
				:key="'sketch-item-' + index"
			>
				<el-dropdown trigger="click" class="menu-btn">
					<Menu />
					<template #dropdown>
						<el-dropdown-menu>
							<el-dropdown-item
								class="sketch-item flex align-center"
								@click="handleClickQuote(item)"
							>
								<img
									src="@/assets/images/restore-sketch.png"
									class="dropdown-icon restore"
								/>
								<span class="dropdown-txt">{{ $t('agent.quote') }}</span>
							</el-dropdown-item>
							<el-dropdown-item
								class="sketch-item flex align-center"
								@click="handleClickDelete(item)"
							>
								<img
									src="@/assets/images/delete.png"
									class="dropdown-icon delete"
								/>
								<span class="dropdown-txt del">{{ $t('agent.delete') }}</span>
							</el-dropdown-item>
						</el-dropdown-menu>
					</template>
				</el-dropdown>
				<div
					class="edit-btn flex align-center space-between"
					@click="handleClickEdit(item)"
				>
					<div>{{ $t('agent.edit') }}</div>
					<img src="@/assets/images/arrow-top-right.png" />
				</div>
				<!-- 已加载完成的 sketch 显示实际图片 -->
				<img v-img-loading="getImageSrc(item, index)" @load="handleImageLoad(index)" />
				<!-- 正在加载的 sketch 显示 loading gif overlay -->
				<!-- <div v-if="pendingSketchIndexes.includes(index)" class="loading-wrapper">
					<img src="@/assets/images/sketch-loading.gif" alt="loading" />
				</div> -->
			</div>
		</template>
		<template v-else-if="type === 'url'">
			<TransitionGroup name="url-card" class="url-list flex" tag="div">
				<div class="url-item flex flex-col" v-for="item in urlList" :key="item.url">
					<div class="url-title" v-ellipsis="3" @click="handleClickUrl(item)">
						{{ item.title }}
						<img src="@/assets/images/link-outer.png" class="link-outer" />
					</div>
					<div class="url-link" v-ellipsis="3">{{ item.url }}</div>
				</div>
			</TransitionGroup>
		</template>
		<div v-else class="reportBorder">
			<div class="report">
				<!-- <div v-if="false" class="report-content-null">
					<img :src="reportNull" alt="" />
				</div> -->
				<template v-if="reportType === 'report'">
					<div class="report-content">
						<div class="downBtnBox">
							<div class="downBtn" @click="handleDownloadMd">
								<div class="icon">
									<SvgIcon name="reportDown" size="16"></SvgIcon>
								</div>
								<span>{{ $t('agent.Download') }}</span>
							</div>
						</div>
						<div class="content">
							<VueMarkdown
								:custom-attrs="customAttrs"
								:markdown="markdownContent"
								:rehype-plugins="[rehypeRaw]"
							>
							</VueMarkdown>
						</div>
					</div>
				</template>
			</div>
		</div>
	</div>
</template>

<script setup lang="ts">
	import { ref, reactive, onMounted, onUnmounted, watch, computed, nextTick } from 'vue'
	import { deleteSketchFlowCanvas } from '@/api/flow-canvas'
	import { useProjectStore } from '@/stores'
	import { useI18n } from 'vue-i18n'
	import { VueMarkdown } from '@crazydos/vue-markdown'
	import type { CustomAttrs } from '@crazydos/vue-markdown'
	import rehypeRaw from 'rehype-raw'
	import Menu from './Menu.vue'
	import LoadingImg from '@/assets/images/sketch-loading.gif'
	import reportNull from '@/assets/images/reportNull.png'
	import myEvent from '@/utils/myEvent'
	import { fetchUrlTitle } from '@/api/agent'

	const projectStore = useProjectStore()
	import MyEvent from '@/utils/myEvent'

	const { t } = useI18n()
	const emits = defineEmits(['deleteSketch'])

	// 存储每个图片的加载状态
	const loadedStatus = ref<boolean[]>([])
	const containerRef = ref<HTMLElement>()

	const props = withDefaults(
		defineProps<{
			type: 'sketch' | 'report' | 'url'
			sketchList: Array<Record<string, string>>
		}>(),
		{
			type: 'sketch',
			sketchList: []
		}
	)

	watch(
		() => props.type,
		(val) => {
			if (val === 'sketch') {
				fetchedUrlSet.value = new Set()
				urlList.value = []
			}
		}
	)

	watch(
		() => props.sketchList,
		() => {
			// 当 sketchList 变化时，重置加载状态
			loadedStatus.value = new Array(combineSketchList.value.length).fill(false)
			// 当 type 为 sketch 时，自动滚动到最底部
			if (props.type === 'sketch') {
				nextTick(() => {
					containerRef.value?.scrollTo({
						top: containerRef.value.scrollHeight,
						behavior: 'smooth'
					})
				})
			}
		}
	)

	const combineSketchList = computed(() => {
		const res: Array<{ id: string; url: string }> = []
		props.sketchList.forEach((group) => {
			Object.entries(group).forEach(([id, url]) => {
				res.push({ id, url })
			})
		})
		return res
	})

	const customAttrs: CustomAttrs = {
		heading: {
			style: {
				fontFamily: 'Regular',
				lineHeight: 2
				// fontSize: '1.4rem'
			}
		},
		p: {
			style: {
				fontSize: '1.4rem',
				lineHeight: 1.5
			}
		},
		img: {
			style: 'max-width: 100%;display:block;'
		},
		a: (node, combinedAttrs) => {
			if (typeof node.properties.href === 'string') {
				return { target: '_blank', rel: 'noopener noreferrer' }
			} else {
				return {}
			}
		}
	}

	const sessionId = ref('')
	const markdownContent = ref('')
	const urlList = ref([])
	const reportType = ref<'report' | 'urls'>('report')
	const reportTitle = ref('')

	const setSessionId = (id: string) => {
		reportType.value = 'report'
		sessionId.value = id
	}

	const setReport = (title: string, content: string) => {
		reportTitle.value = title
		markdownContent.value = content
	}

	const urlLoading = ref(false)
	const fetchedUrlSet = ref<Set<string>>(new Set())

	const BATCH_SIZE = 4
	let isFetchingUrls = false
	let pendingUrlList: string[] | null = null

	const fetchBatch = async (batch: string[]) => {
		const res = await fetchUrlTitle(batch)
		batch.forEach((url) => fetchedUrlSet.value.add(url))
		urlList.value = [...urlList.value, ...res]
	}

	const setUrls = async (list: string[]) => {
		reportType.value = 'urls'
		const newUrls = [...new Set(list.filter((url) => !fetchedUrlSet.value.has(url)))]
		if (newUrls.length === 0) return

		if (isFetchingUrls) {
			pendingUrlList = list
			return
		}

		isFetchingUrls = true
		if (urlList.value.length < 1) {
			urlLoading.value = true
		}
		for (let i = 0; i < newUrls.length; i += BATCH_SIZE) {
			const batch = newUrls.slice(i, i + BATCH_SIZE)
			await fetchBatch(batch)
			urlLoading.value = false
		}
		isFetchingUrls = false

		if (pendingUrlList) {
			const next = pendingUrlList
			pendingUrlList = null
			setUrls(next)
		}
	}
	// watch(
	// 	() => sessionId.value,
	// 	(newVal) => {
	// 		if (newVal) {
	// 			markdownContent.value = sessionStorage.getItem(`reportsContent_${newVal}`)
	// 		}
	// 	}
	// )

	// 图片加载完成时触发
	const handleImageLoad = (index: number) => {
		loadedStatus.value[index] = true
	}

	// 图片加载失败时触发
	const handleImageError = (index: number) => {
		console.error(`Failed to load sketch at index ${index}`)
	}

	// 获取当前显示的图片源
	const getImageSrc = (item: { id: string; url: string }, index: number) => {
		return item.url
	}

	const handleClickEdit = (item: { id: string; url: string }) => {
		const url = item.url
		const imgId = item.id
		const nodeId = projectStore.state.nodeId
		myEvent.emit('openFlowCanvas', { url, imgId, nodeId })
	}

	const handleClickQuote = (item: { id: string; url: string }) => {
		const url = item.url
		MyEvent.emit('quote', url)
	}

	const handleClickDelete = (item: { id: string; url: string }) => {
		ElMessageBox.confirm(t('agent.deleteSketchTip'), t('agent.confirm'), {
			confirmButtonText: t('agent.confirm'),
			cancelButtonText: t('agent.cancel'),
			type: 'warning'
		}).then(() => {
			deleteSketchFlowCanvas({
				id: item.id,
				versionNodeId: projectStore.state.nodeId
			}).then((res) => {
				if (res) {
					ElMessage.success(t('agent.deleteSuccess'))
					emits('deleteSketch', item.id)
				}
			})
		})
	}

	const handleDownloadMd = () => {
		if (!markdownContent.value) return

		const blob = new Blob([markdownContent.value], { type: 'text/markdown' })
		const url = URL.createObjectURL(blob)
		const link = document.createElement('a')
		link.href = url
		link.download = reportTitle.value ?? `report-${Date.now()}.md`
		document.body.appendChild(link)
		link.click()
		document.body.removeChild(link)
		URL.revokeObjectURL(url)
	}

	const handleClickUrl = (item: { url: string; title: string }) => {
		window.open(item.url, '_blank')
	}

	const vImgLoading = {
		mounted(el, binding) {
			// 1. 设置初始状态：显示 Loading 图（或者你可以从 binding.arg 传进来）
			const loadingUrl = LoadingImg
			const finalSrc = binding.value // 真正要加载的图

			el.src = loadingUrl

			// 2. 预加载真实图片
			const img = new Image()
			img.src = finalSrc
			img.onload = () => {
				// 3. 加载完成后替换
				el.src = finalSrc
				el.style.opacity = 1
			}
		},
		// 关键：如果图片地址是动态变化的，需要监听更新
		updated(el, binding) {
			if (binding.value !== binding.oldValue) {
				console.log('value', binding.value, 'oldValue', binding.oldValue)

				// 重复上面的加载逻辑...
				const loadingUrl = LoadingImg
				const finalSrc = binding.value // 真正要加载的图

				el.src = loadingUrl

				// 2. 预加载真实图片
				const img = new Image()
				img.src = finalSrc
				img.onload = () => {
					// 3. 加载完成后替换
					el.src = finalSrc
					el.style.opacity = 1
				}
			}
		}
	}

	defineExpose({
		setSessionId,
		setUrls,
		setReport
	})
</script>

<style lang="less" scoped>
	.preview-container {
		width: 100%;
		height: 100%;
		gap: 1.2rem;
		flex-wrap: wrap;
		overflow-y: auto;
		align-content: flex-start;
		.sketch-item {
			position: relative;
			width: calc((100% - 1.2rem * 3) / 4);
			aspect-ratio: 1 / 1;
			border-radius: 1.6rem;
			background-color: #fff;
			img {
				width: 100%;
				// height: 100%;
				border-radius: 1.6rem;
			}
			.loading-wrapper {
				position: absolute;
				top: 0;
				left: 0;
				width: 100%;
				height: 100%;
				border-radius: 1.6rem;
				img {
					width: 100%;
					height: 100%;
					border-radius: 1.6rem;
				}
			}
			:deep(.menu-btn) {
				position: absolute;
				top: 2.1rem;
				right: 1.5rem;

				.dropdown-icon {
					&.restore {
						width: 1.4rem;
						height: 1.3rem;
					}
					&.delete {
						width: 1.19rem;
						height: 1.3rem;
					}
				}
			}
			.edit-btn {
				position: absolute;
				right: 1rem;
				bottom: 1.1rem;
				width: 7.8rem;
				height: 3.59rem;
				border-radius: 2rem;
				background-color: #fff;
				border: 0.2rem solid #e5e5e5;
				font-size: 1.4rem;
				padding: 0 0.9rem 0 1.4rem;
				cursor: pointer;
				img {
					width: 1.8rem;
					height: 1.8rem;
				}
			}
		}
		.url-card-enter-active {
				animation: urlCardIn 0.4s ease-out;
			}
			@keyframes urlCardIn {
				from {
					opacity: 0;
					transform: translateY(2rem) scale(0.95);
				}
				to {
					opacity: 1;
					transform: translateY(0) scale(1);
				}
			}
		.url-list {
			flex: 1;
			flex-wrap: wrap;
			column-gap: 4rem;
			row-gap: 3rem;
			.url-item {
				width: 24rem;
				height: 28.7rem;
				line-height: 2rem;
				word-break: break-all;
				background: url('@/assets/images/web-card.png') no-repeat;
				background-size: 100% 100%;
				padding: 5rem 1.5rem;
				row-gap: 0.6rem;
				// .url-title,.url-link{
				// 	// 两行省略
				// 	display: -webkit-box;
				// 	-webkit-line-clamp: 2;
				// 	line-clamp: 2;
				// 	-webkit-box-orient: vertical;
				// 	overflow: hidden;
				// 	text-overflow: ellipsis;
				// }
				.url-title {
					cursor: pointer;
					font-family: 'Medium';
					font-size: 1.6rem;
					color: #232323;
					max-height: 4rem;
					.link-outer {
						width: 1.2rem;
						height: 1.2rem;
					}
				}
				.url-link {
					font-family: 'Medium';
					font-style: italic;
					font-size: 1.2rem;
					color: #7c7c7c;
					user-select: text;
				}
			}
		}
		.reportBorder {
			position: relative;
			display: flex;
			align-items: center;
			justify-content: center;
			--border-width: 3px;
			flex: 1;
			overflow: hidden;
			height: 100%;

			&::before {
				content: '';
				position: absolute;
				background: linear-gradient(
					119.03deg,
					rgba(233, 121, 60, 0.3) 1.61%,
					rgba(255, 207, 144, 0.3) 101.01%
				);
				border-radius: 2.3rem;
				z-index: -1;
				width: 100%;
				height: 100%;
				left: -50%;
				top: -50%;
				transform: translate(50%, 50%);
			}
			.report {
				background-color: #fff;
				width: calc(100% - var(--border-width) * 2);
				height: calc(100% - var(--border-width) * 2);
				border-radius: 2rem;
				display: flex;
				.report-content-null {
					flex: 1;
					display: flex;
					align-items: center;
					justify-content: center;
				}
				.report-content {
					flex: 1;
					display: flex;
					flex-direction: column;
					overflow: hidden;
					.downBtnBox {
						padding: 2.2rem 5.2rem 0;
						.downBtn {
							display: flex;
							width: 11.2rem;
							justify-content: center;
							margin-left: auto;
							line-height: 3.2rem;
							border-radius: 5px;
							background-color: #ff7a51;
							color: #fff;
							cursor: pointer;
							.icon {
								margin-right: 0.02rem;
							}
							span {
								font-weight: 500;
								font-size: 1.2rem;
							}
						}
					}
					.content {
						word-break: break-word;
						white-space: pre-wrap;
						overflow-y: auto;
						margin: 2rem;
						padding: 0 8.8rem 8.8rem;
						user-select: text;
					}
				}
			}
		}
	}
	:deep(.el-dropdown-menu__item) {
		column-gap: 1.2rem;
		padding: 1.2rem 1.4rem;
		.dropdown-txt {
			font-size: 1.3rem;
			font-family: 'Medium';
			color: #000;
			&.del {
				color: #ff4747;
			}
		}
	}
</style>
