<template>
	<el-drawer v-model="visible" :close-on-click-modal="false" size="100%" :destroy-on-close="false" direction="rtl" class="report-generator-drawer">
		<template #title>
			<div class="flex items-center gap-3 py-1">
				<h2 class="max-w-md text-lg font-semibold text-gray-800 truncate">{{ reportTitle }}</h2>
			</div>
		</template>
		<div class="h-full px-4 py-2">
			<!-- Splitpanes容器 -->
			<div class="h-[calc(100vh-100px)] flex w-full">
				<!-- 左侧面板 - 文档预览 -->
				<div class="w-[45%] min-w-[30%] overflow-auto transition-all duration-150 ease-in-out pr-3">
					<div class="h-full transition-shadow duration-200 border border-gray-200 rounded-lg shadow-sm hover:shadow-md">
						<!-- 卡片头部 -->
						<div class="flex items-center justify-between px-4 py-3 border-b border-gray-100 rounded-t-lg bg-gray-50">
							<span class="font-medium text-gray-700">文档预览</span>
							<button
								v-if="documentData"
								@click="downloadDocument"
								class="flex items-center px-3 py-1 text-sm text-white transition-colors duration-200 rounded bg-primary hover:bg-primary-dark"
							>
								<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
									<path
										stroke-linecap="round"
										stroke-linejoin="round"
										stroke-width="2"
										d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
									/>
								</svg>
								下载文档
							</button>
						</div>

						<!-- 卡片内容 -->
						<div class="p-3 h-[calc(100%-55px)] overflow-auto">
							<!-- 加载中状态 -->
							<div v-if="previewLoading" class="flex items-center justify-center h-full">
								<el-icon class="mr-2 text-xl is-loading text-primary"><Loading /></el-icon>
								<span class="text-gray-600">文档生成中...</span>
							</div>

							<!-- 预览状态 -->
							<div v-else-if="previewUrl" class="h-full">
								<vue-office-docx
									:src="previewUrl"
									:config="{}"
									@rendered="handleDocRendered"
									@error="handleDocError"
									class="h-full overflow-hidden rounded"
								/>
							</div>

							<!-- 空状态 -->
							<div v-else class="flex flex-col items-center justify-center h-full text-gray-400 rounded-lg bg-gray-50">
								<el-empty description="点击生成按钮预览报告" />
								<p class="mt-2 text-sm text-gray-400">完成右侧表单后点击"生成"按钮</p>
							</div>
						</div>
					</div>
				</div>

				<!-- 分割线 -->
				<div class="w-[6px] bg-gray-100 hover:bg-gray-200 cursor-col-resize mx-1 relative group">
					<div class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[2px] h-[30px] bg-gray-300 rounded group-hover:bg-gray-400"></div>
				</div>

				<!-- 右侧面板 - 报告配置 -->
				<div class="w-[55%] min-w-[30%] overflow-auto transition-all duration-150 ease-in-out pl-3">
					<div class="h-full transition-shadow duration-200 border border-gray-200 rounded-lg shadow-sm hover:shadow-md">
						<!-- 卡片头部 -->
						<div class="px-4 py-3 border-b border-gray-100 rounded-t-lg bg-gray-50">
							<div class="font-medium text-gray-700">报告配置</div>
						</div>

						<!-- 卡片内容 -->
						<div class="p-3 h-[calc(100%-55px)] overflow-auto">
							<el-form ref="formRef" @submit.prevent :model="form" :rules="rules" label-width="80px" v-loading="formLoading" class="p-2">
								<el-row :gutter="24" class="mb-6">
									<el-col :span="12" :xs="24" :sm="24" :md="12">
										<el-form-item label="模型" prop="model" class="mb-4">
											<model-list :model-type="['Chat']" @update:model="handleModelChange" />
										</el-form-item>
									</el-col>
									<el-col :span="12" :xs="24" :sm="24" :md="12">
										<el-form-item label="AI 润色" prop="polish" class="mb-4">
											<el-radio-group v-model="form.polish" class="ml-1">
												<el-radio :key="index" border :label="item.value" v-for="(item, index) in yes_no_type">
													{{ item.label }}
												</el-radio>
											</el-radio-group>
										</el-form-item>
									</el-col>
								</el-row>

								<el-form-item label="提示词" prop="prompt" class="mt-12">
									<ai-editor
										v-if="promptLoaded"
										v-model="form.prompt"
										:placeholder="promptPlaceholder"
										:min-height="450"
										output="text"
										class="w-full"
									/>
									<div v-else class="h-[400px] flex items-center justify-center bg-gray-100 rounded-lg">
										<el-icon class="text-xl is-loading text-primary"><Loading /></el-icon>
										<span class="ml-2 text-gray-600">加载中...</span>
									</div>
								</el-form-item>

								<div class="flex justify-center gap-3 mt-6 sm:justify-end">
									<button
										@click="visible = false"
										class="px-4 py-2 text-gray-700 transition-colors duration-200 border border-gray-300 rounded-md hover:bg-gray-100"
									>
										取 消
									</button>
									<button
										@click="onSubmit"
										:disabled="loading"
										class="min-w-[100px] px-4 py-2 bg-primary text-white rounded-md hover:bg-primary-dark transition-colors duration-200 flex items-center justify-center"
									>
										<svg
											v-if="loading"
											class="w-4 h-4 mr-2 -ml-1 text-white animate-spin"
											xmlns="http://www.w3.org/2000/svg"
											fill="none"
											viewBox="0 0 24 24"
										>
											<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
											<path
												class="opacity-75"
												fill="currentColor"
												d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
											></path>
										</svg>
										<svg v-else xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
											<path
												stroke-linecap="round"
												stroke-linejoin="round"
												stroke-width="2"
												d="M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
											/>
										</svg>
										生 成
									</button>
								</div>
							</el-form>
						</div>
					</div>
				</div>
			</div>
		</div>
	</el-drawer>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { useMessage } from '/@/hooks/message';
import { generateReport, getObj } from '/@/api/knowledge/aiReportConf';
import { handleBlobFile } from '/@/utils/other';
import ModelList from '/@/views/knowledge/aiChat/components/widgets/modelList.vue';
import { useDict } from '/@/hooks/dict';
import AiEditor from '/@/components/AiEditor/index.vue';
import { Loading } from '@element-plus/icons-vue';
// @ts-ignore
import VueOfficeDocx from '@vue-office/docx/lib/v3/vue-office-docx.mjs';
import '@vue-office/docx/lib/v3/index.css';
import 'splitpanes/dist/splitpanes.css';

// 字典
const { yes_no_type } = useDict('yes_no_type');

// 定义变量
const visible = ref(false);
const loading = ref(false);
const formLoading = ref(false);
const previewLoading = ref(false);
const formRef = ref();
const promptPlaceholder = ref('请输入提示词');
const promptLoaded = ref(false);
const previewUrl = ref('');
const documentData = ref<any>(null); // 存储文档数据用于下载
const reportTitle = ref('生成报告'); // 动态设置标题

// 表单数据
const form = reactive({
	reportId: '',
	model: '',
	prompt: '',
	polish: '1', // 默认选择"是"
});

// 表单校验规则
const rules = {
	model: [{ required: true, message: '请选择模型', trigger: 'change' }],
	prompt: [{ required: true, message: '请输入提示词', trigger: 'blur' }],
	polish: [{ required: true, message: '请选择是否润色', trigger: 'change' }],
};

// 打开弹窗
const openDialog = async (id: string) => {
	visible.value = true;
	form.reportId = id;
	formLoading.value = true;
	promptLoaded.value = false;
	previewUrl.value = '';
	documentData.value = null;

	try {
		// 查询报告详情
		const { data } = await getObj(id);
		if (data) {
			// 设置提示词的placeholder
			promptPlaceholder.value = data.reportPrompt;
			// 设置动态标题
			reportTitle.value = data.reportTitle || '生成报告';
			promptLoaded.value = true;
		}
	} catch (error: any) {
		useMessage().error('获取报告详情失败');
		promptLoaded.value = true; // 即使加载失败也允许渲染编辑器
	} finally {
		formLoading.value = false;
	}

	// 重置表单
	formRef.value?.resetFields();
};

// 处理模型选择
const handleModelChange = (model: any) => {
	form.model = model.name;
};

// 处理文档渲染成功
const handleDocRendered = () => {
	useMessage().success('文档加载成功');
};

// 处理文档渲染错误
const handleDocError = () => {
	useMessage().error('文档加载失败');
};

// 提交表单
const onSubmit = async () => {
	try {
		// 表单验证
		await formRef.value.validate();

		loading.value = true;
		previewLoading.value = true;

		// 发送请求生成报告
		const response = await generateReport(form);

		// 保存响应数据用于下载
		documentData.value = response;

		// 为预览创建一个新的Blob对象
		if (response instanceof Blob) {
			previewUrl.value = URL.createObjectURL(response);
		} else if (response.data instanceof Blob) {
			previewUrl.value = URL.createObjectURL(response.data);
		} else {
			// 如果不是Blob，则尝试将响应数据转换为Blob
			const blob = new Blob([response.data || response], {
				type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
			});
			previewUrl.value = URL.createObjectURL(blob);
		}

		useMessage().success('报告生成成功');
	} catch (error: any) {
		useMessage().error(error.msg || '生成失败');
		previewUrl.value = '';
		documentData.value = null;
	} finally {
		loading.value = false;
		previewLoading.value = false;
	}
};

// 下载文档
const downloadDocument = () => {
	if (documentData.value) {
		handleBlobFile(documentData.value, `report-${Date.now()}.docx`);
		useMessage().success('文档下载成功');
	} else {
		useMessage().error('文档数据不存在，请重新生成');
	}
};

// 暴露方法
defineExpose({
	openDialog,
});

// 组件卸载时清理资源
onMounted(() => {
	return () => {
		if (previewUrl.value) {
			URL.revokeObjectURL(previewUrl.value);
		}
	};
});
</script>

<style>
/* El-drawer header 样式 */
.report-generator-drawer .el-drawer__header {
	@apply mb-0 px-5 py-4 border-b border-gray-100;
}

/* 媒体查询 */
@media (max-width: 768px) {
	.report-generator-drawer [class^='w-['] {
		@apply w-full min-h-[400px];
	}
}
</style>
