<template>
	<div class="layout-padding">
		<div class="layout-padding-auto layout-padding-view">
			<div class="flex overflow-hidden h-full rounded-xl shadow-lg">
				<!-- Left Panel: Controls -->
				<div class="w-1/4 min-w-[320px] bg-white p-5 border-r border-slate-200 overflow-y-auto">
					<!-- Model Selection -->
					<div class="mb-6">
						<div class="flex justify-between items-center">
							<label class="text-sm font-medium text-slate-700">模型</label>
							<div class="flex-grow ml-4">
								<ModelList ref="modelListComponent" :model-type="['Video']" />
							</div>
						</div>
					</div>

					<!-- Video Size Selection -->
					<div class="mb-6">
						<label class="block mb-2 text-sm font-medium text-slate-700">视频尺寸</label>
						<div class="grid grid-cols-3 gap-2">
							<div
								v-for="size in imageSizes"
								:key="size.value"
								@click="selectedimageSize = size.value"
								:class="[
									'flex relative justify-center items-center p-1 border rounded-lg transition-all duration-200',
									selectedimageSize === size.value
										? 'bg-blue-50 border-blue-500 text-blue-600 shadow-sm'
										: 'bg-white border-slate-200 hover:bg-slate-50',
								]"
							>
								<div class="flex flex-col justify-center items-center py-2 w-full">
									<div class="flex relative justify-center items-center mb-1 w-10 h-7 rounded border border-dashed border-slate-300">
										<img v-if="size.iconName" :src="getIconUrl(size.iconName)" :alt="size.label" class="object-contain w-full h-full" />
									</div>
									<span class="text-xs font-medium">{{ size.label }}</span>
								</div>
							</div>
						</div>
					</div>

					<!-- Additional Controls -->
					<div class="space-y-5">
						<!-- Seed Input -->
						<div class="mb-1">
							<label class="block mb-1.5 text-sm font-medium text-slate-700">种子</label>
							<div class="flex items-center space-x-2">
								<el-input v-model="seed" placeholder="随机种子" class="flex-grow"></el-input>
								<el-button :icon="RefreshRight" @click="randomizeSeed" class="flex-shrink-0 hover:bg-blue-50"></el-button>
							</div>
						</div>

						<!-- Negative Prompts -->
						<div class="mb-1">
							<label class="block mb-1.5 text-sm font-medium text-slate-700">反向提示词</label>
							<el-input type="textarea" :rows="3" v-model="negativePrompt" placeholder="不想在视频中看到的内容" class="w-full"></el-input>
						</div>

						<!-- Debug Mode -->
						<div class="px-3 py-1 rounded-lg bg-slate-50">
							<div class="flex justify-between items-center">
								<label class="text-sm font-medium text-slate-700">调试模式</label>
								<el-switch v-model="debugMode" />
							</div>
							<p class="mt-1 text-xs text-slate-500">开启后将使用本地测试数据，不会调用真实API</p>
						</div>

						<!-- Reference Image Upload -->
						<div class="p-3 mt-4 mb-1 rounded-lg bg-slate-50">
							<div class="flex justify-between items-center mb-2">
								<label class="text-sm font-medium text-slate-700">参考图片</label>
								<el-upload
									class="flex justify-start"
									:auto-upload="false"
									:limit="1"
									:on-change="handleImageUpload"
									:on-remove="handleImageRemove"
									accept="image/*"
								>
									<template #trigger>
										<div class="flex">
											<el-button type="primary" size="small" class="text-xs">选择图片</el-button>
										</div>
									</template>
								</el-upload>
							</div>
							<div v-if="uploadedImageBase64" class="flex justify-center mt-2">
								<div class="overflow-hidden relative w-full max-h-40 rounded-md">
									<img :src="uploadedImageBase64" class="object-contain w-full" alt="参考图片" />
								</div>
							</div>
						</div>
					</div>
				</div>

				<!-- Middle Panel: Video Display & Prompt Input -->
				<div class="flex flex-col flex-grow p-5 bg-white">
					<!-- Video Display Area -->
					<div class="flex overflow-hidden relative flex-col flex-grow mb-6 rounded-xl shadow-inner bg-slate-100">
						<div v-if="generatedVideoUrl" class="w-full h-full">
							<div class="flex justify-center items-center p-4 w-full h-full">
								<video
									controls
									autoplay
									class="object-contain max-w-full max-h-full rounded-lg shadow-md"
									:src="baseURL + generatedVideoUrl"
									:poster="posterUrl"
								></video>
							</div>
						</div>
						<div v-else-if="isGenerating" class="flex flex-col justify-center items-center h-full">
							<el-icon class="text-blue-500 animate-spin" size="48"><Loading /></el-icon>
							<span class="px-8 mt-4 text-center text-slate-600">{{ generatingMessage }}</span>
						</div>
						<div v-else class="flex justify-center items-center h-full">
							<div class="text-center">
								<el-icon class="mb-2 text-slate-400" size="48"><VideoCamera /></el-icon>
								<p class="text-slate-500">视频将在这里显示</p>
							</div>
						</div>
					</div>

					<!-- Example Prompts -->
					<div class="mb-5">
						<div class="flex justify-between items-center mb-2">
							<h3 class="flex items-center text-sm font-medium text-slate-700">
								示例提示词
								<el-tooltip content="点击使用示例提示词" placement="top">
									<el-icon class="ml-1 text-slate-400"><InfoFilled /></el-icon>
								</el-tooltip>
							</h3>
						</div>
						<div class="grid grid-cols-1 gap-2 pb-1">
							<div
								v-for="example in examplePrompts"
								:key="example"
								@click="prompt = example"
								class="flex items-center p-2.5 bg-white rounded-lg border transition-colors cursor-pointer border-slate-200 hover:bg-blue-50 hover:border-blue-300"
							>
								<el-icon class="mr-2 text-blue-500"><VideoPlay /></el-icon>
								<div class="overflow-hidden">
									<p class="text-sm truncate">{{ truncateText(example, 40) }}</p>
								</div>
							</div>
						</div>
					</div>

					<!-- Prompt Input Area -->
					<div class="flex items-center p-3 bg-white rounded-xl border shadow-sm border-slate-200">
						<el-input
							v-model="prompt"
							placeholder="请输入你的视频创意指令... "
							class="flex-grow mr-3 prompt-input"
							@keyup.enter.prevent="handlePromptEnter"
							autosize
							type="textarea"
							:maxlength="500"
							:input-style="{ border: 'none', boxShadow: 'none', padding: '8px 0px', lineHeight: '1.5', resize: 'none' }"
							resize="none"
						>
						</el-input>
						<el-button
							circle
							type="primary"
							@click="generateVideo"
							:loading="isGenerating"
							class="flex justify-center items-center w-12 h-12 min-w-[3rem] min-h-[3rem] rounded-full shadow-md transition-all hover:shadow-lg transform hover:scale-105"
							:disabled="!prompt.trim() || !uploadedImageBase64"
						>
							<el-icon size="24"><VideoCamera /></el-icon>
						</el-button>
					</div>
				</div>

				<!-- Right Panel: History -->
				<div class="w-1/4 min-w-[280px] bg-white border-l border-slate-200">
					<HistoryPanel
						ref="historyPanelRef"
						material-type="Video"
						thumbnailAlt="Video thumbnail"
						@item-click="loadHistoryVideo"
						:show-time-column="true"
						:show-status-column="true"
					/>
				</div>
			</div>
		</div>
	</div>
</template>

<script lang="ts" setup>
import { ref, onUnmounted } from 'vue';
import { RefreshRight, Loading, InfoFilled, VideoPlay, VideoCamera } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import ModelList from './components/widgets/modelList.vue';
import HistoryPanel, { type HistoryItem } from './components/widgets/historyPanel.vue';
import { generateVideoCompletion, getVideoCompletionStatus, type VideoCompletionParams } from '/@/api/knowledge/aiGen';
import { Local } from '/@/utils/storage';
import { useIntervalFn } from '@vueuse/core';

// Import SVG icons
import imageSize11 from '/@/assets/ai/images/image-size-1-1.svg';
import imageSize169 from '/@/assets/ai/images/image-size-16-9.svg';
import imageSize916 from '/@/assets/ai/images/image-size-9-16.svg';

// SVG icon mapping
const iconMap: Record<string, string> = {
	'image-size-1-1': imageSize11,
	'image-size-16-9': imageSize169,
	'image-size-9-16': imageSize916,
};

// 获取图标URL的辅助函数
const getIconUrl = (iconName: string) => {
	return iconMap[iconName] || '';
};

// 文本截断的辅助函数
const truncateText = (text: string, maxLength: number) => {
	return text?.length > maxLength ? text.substring(0, maxLength) + '...' : text || '';
};

// 左侧面板: 控制数据
const modelListComponent = ref<any>(null); // 模型选择组件引用
const imageSizes = ref([
	{ label: '16:9', value: '1280x720', iconName: 'image-size-16-9' }, // 标准视频比例
	{ label: '9:16', value: '720x1280', iconName: 'image-size-9-16' }, // 手机竖屏视频
	{ label: '1:1', value: '960x960', iconName: 'image-size-1-1' }, // 方形视频
]);

const selectedimageSize = ref('1280x720'); // 默认视频尺寸为16:9
const seed = ref(''); // 随机种子值
const negativePrompt = ref<string | null>(null); // 反向提示词，指定不希望在视频中出现的内容
const uploadedImageBase64 = ref<string | null>(null); // 上传图片的Base64编码
const uploadedImageFile = ref<File | null>(null); // 上传的图片文件对象
const debugMode = ref(true); // 调试模式开关，默认关闭

// 右侧面板: 数据
const generatedVideoUrl = ref<string>(''); // 当前显示的生成视频URL
const posterUrl = ref<string>(''); // 视频封面图URL
const historyPanelRef = ref<InstanceType<typeof HistoryPanel> | null>(null); // 历史面板组件引用
const prompt = ref(''); // 提示词输入
const isGenerating = ref(false); // 是否正在生成视频
const generatingMessage = ref('正在生成视频...'); // 生成过程中的提示消息
const progress = ref(0); // 视频生成进度
const currentTaskId = ref<string | null>(null); // 当前任务ID
const pollAttempts = ref(0); // 轮询尝试次数计数器

// 处理图片上传
const handleImageUpload = (file: any) => {
	if (file.raw && file.raw.type && file.raw.type.startsWith('image/')) {
		uploadedImageFile.value = file.raw;
		const reader = new FileReader();
		reader.onload = (e) => {
			if (e.target && e.target.result) {
				uploadedImageBase64.value = e.target.result.toString(); // 转换为Base64
			}
		};
		reader.readAsDataURL(file.raw);
		return false; // 阻止自动上传
	}

	ElMessage.error('请上传有效的图片文件');
	return false;
};

// 处理图片移除
const handleImageRemove = () => {
	uploadedImageFile.value = null;
	uploadedImageBase64.value = null;
};

const examplePrompts = ref([
	// 示例提示词列表
	'一只小猫在草地上奔跑玩耍，阳光明媚，自然环境',
	'城市夜景，街道上的车流形成光线轨迹，摩天大楼灯光闪烁',
	'海洋波浪拍打海岸，日落时分，金色阳光洒在水面上',
	'宇宙行星环绕恒星旋转，星云闪烁，史诗宇宙场景',
	'瀑布从高山流下，四周是郁郁葱葱的森林，鸟儿飞过',
]);

// 左侧面板: 方法
// 生成随机种子
const randomizeSeed = () => {
	seed.value = String(Math.floor(Math.random() * 100000));
};

// 右侧面板: 方法
// 处理回车键按下事件
const handlePromptEnter = (event: KeyboardEvent) => {
	if (event.shiftKey) {
		// 允许Shift+Enter换行
		return;
	}
	generateVideo(); // 直接回车则生成视频
};

// 轮询函数 - 使用VueUse的useIntervalFn
const { pause, resume } = useIntervalFn(
	async () => {
		try {
			const selectedModel = Local.get(`selectedAiModel:Video`);

			const { data } = await getVideoCompletionStatus(currentTaskId.value!, selectedModel.name);

			if (data) {
				if (data.status === 'Failed') {
					const reason = data.reason ? `: ${data.reason}` : '';
					ElMessage.error(`视频生成失败${reason}`);
					stopPolling();
					isGenerating.value = false;
				} else if (data.status === 'Succeed') {
					if (data.results && data.results.videos && data.results.videos.length > 0) {
						const firstVideo = data.results.videos[0];
						generatedVideoUrl.value = firstVideo.url;
						posterUrl.value = firstVideo.thumbnailUrl || '';

						// 刷新服务器历史数据
						historyPanelRef.value?.refreshHistory();

						ElMessage.success('视频生成成功!');
					} else {
						ElMessage.error('视频生成成功，但未找到视频数据。');
					}
					stopPolling();
					isGenerating.value = false;
				} else if (data.status === 'InProgress') {
					generatingMessage.value = `视频生成预计10分钟内返回结果，可关闭此页面，再右侧历史生成中双击查看结果`;
				} else {
					generatingMessage.value = `视频生成预计10分钟内返回结果，可关闭此页面，再右侧历史生成中双击查看结果`;
				}
			}
		} catch (error) {
			ElMessage.error(`轮询视频状态出错: ${error instanceof Error ? error.message : '未知错误'}`);
		}

		pollAttempts.value++;
		if (pollAttempts.value >= 30) {
			ElMessage.warning('视频生成时间过长，已停止等待');
			stopPolling();
			isGenerating.value = false;
		}
	},
	5000,
	{ immediate: false }
);

// 停止轮询
const stopPolling = () => {
	pause();
	pollAttempts.value = 0;
};

// 生成视频的核心方法
const generateVideo = async () => {
	if (!prompt.value.trim()) {
		ElMessage.warning('请输入提示词!');
		return;
	}

	if (!uploadedImageBase64.value) {
		ElMessage.warning('请上传参考图片!');
		return;
	}

	if (isGenerating.value) {
		ElMessage.warning('视频正在生成中，请稍候...');
		return;
	}

	isGenerating.value = true;
	generatedVideoUrl.value = '';
	generatingMessage.value = '视频生成预计10分钟内返回结果，可关闭此页面，再右侧历史生成中双击查看结果';
	progress.value = 0;
	pollAttempts.value = 0;

	try {
		const selectedModel = Local.get(`selectedAiModel:Video`);

		const params: VideoCompletionParams = {
			model: selectedModel.name,
			imageSize: selectedimageSize.value,
			seed: seed.value ? Number(seed.value) : undefined,
			negativePrompt: negativePrompt.value || undefined,
			prompt: prompt.value,
			image: uploadedImageBase64.value || undefined,
		};

		if (debugMode.value) {
			// 调试模式：使用固定的TaskID，不调用实际API
			currentTaskId.value = 'to9j43xb98j9';
			generatingMessage.value = '视频正在生成中，请稍候...';
		} else {
			// 生产模式：调用实际API
			const { data } = await generateVideoCompletion(params);

			if (data) {
				currentTaskId.value = data;
				generatingMessage.value = '视频正在生成中，请稍候...';
				// 开始轮询检查视频生成状态
				resume();
			} else {
				ElMessage.error('提交视频生成请求失败');
				isGenerating.value = false;
			}
		}
	} catch (error) {
		const errorMessage = error instanceof Error ? error.message : 'Unknown error';
		ElMessage.error(`提交视频生成请求失败: ${errorMessage}`);
		isGenerating.value = false;
	}
};

// 从历史记录中加载视频
const loadHistoryVideo = (video: HistoryItem) => {
	generatedVideoUrl.value = video.localUrl || video.url;
	posterUrl.value = video.thumbnail;
	prompt.value = video.prompt || '';
};

// 组件销毁前清除轮询定时器
onUnmounted(() => {
	stopPolling();
});

// 组件初始化时生成随机种子
randomizeSeed();
</script>
