<template>
	<el-drawer v-model="visible" :title="form.id ? '编辑' : '新增'" size="50%">
		<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="auto" v-loading="loading">
			<!-- Tab buttons -->
			<div role="tablist" class="mb-5 tabs tabs-boxed abs-bordered">
				<a role="tab" class="tab" :class="{ 'tab-active': activeTab === 'basic' }" @click="activeTab = 'basic'"
					><span class="inline-flex justify-center items-center mr-2 w-5 h-5 text-white rounded-full bg-primary">1</span>基础配置</a
				>
				<a role="tab" class="tab" :class="{ 'tab-active': activeTab === 'advanced' }" @click="activeTab = 'advanced'"
					><span class="inline-flex justify-center items-center mr-2 w-5 h-5 text-white rounded-full bg-primary">2</span>高级配置</a
				>
				<a role="tab" class="tab" :class="{ 'tab-active': activeTab === 'security' }" @click="activeTab = 'security'"
					><span class="inline-flex justify-center items-center mr-2 w-5 h-5 text-white rounded-full bg-primary">3</span>安全配置</a
				>
			</div>

			<!-- Basic Configuration Tab -->
			<div v-show="activeTab === 'basic'" class="px-2">
				<el-row :gutter="30">
					<el-col :span="12" class="mb-6">
						<el-form-item label="头像" prop="avatarUrl">
							<upload-img v-model:image-url="form.avatarUrl" />
						</el-form-item>
					</el-col>
					<el-col :span="12" class="mb-6">
						<!-- Placeholder for alignment -->
					</el-col>
				</el-row>

				<el-row :gutter="30">
					<el-col :span="12" class="mb-6">
						<el-form-item label="名称" prop="name">
							<el-input v-model="form.name" maxlength="20" placeholder="请输入名称" />
						</el-form-item>
					</el-col>
					<el-col :span="12" class="mb-6">
						<el-form-item prop="sortOrder">
							<template #label>
								排序值
								<tip content="越大展示越靠前" />
							</template>
							<el-input-number v-model="form.sortOrder" :min="1" :max="9999" :step="1" />
						</el-form-item>
					</el-col>
				</el-row>

				<el-row :gutter="30">
					<el-col :span="24" class="mb-6">
						<el-form-item label="欢迎语" prop="welcomeMsg">
							<el-input
								v-model="form.welcomeMsg"
								type="textarea"
								placeholder="描述知识库的内容，详尽的描述将帮助AI能深入理解该知识库的内容，能更准确的检索到内容，提高该知识库的命中率。"
								maxlength="1024"
								show-word-limit
								rows="10"
							/>
						</el-form-item>
					</el-col>
				</el-row>
			</div>

			<!-- Advanced Configuration Tab -->
			<div v-show="activeTab === 'advanced'" class="px-2">
				<el-divider content-position="left">模型配置</el-divider>

				<el-row :gutter="30" class="mb-6">
					<el-col :span="12">
						<el-form-item label="向量库" prop="storeId">
							<el-select v-model="form.storeId" placeholder="请选择向量库" clearable filterable :disabled="form.id !== ''">
								<el-option v-for="item in storeList" :key="item.storeId" :label="item.name" :value="item.storeId" />
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="向量模型" prop="embeddingModel">
							<el-select v-model="form.embeddingModel" placeholder="请选择向量模型" clearable filterable :disabled="form.id !== ''">
								<el-option v-for="item in embeddingModelList" :key="item.id" :label="item.name" :value="item.name" />
							</el-select>
						</el-form-item>
					</el-col>
				</el-row>

				<el-row :gutter="30" class="mb-6">
					<el-col :span="12">
						<el-form-item label="总结模型" prop="summaryModel">
							<el-select v-model="form.summaryModel" placeholder="请选择总结模型" clearable filterable>
								<el-option v-for="item in chatModelList" :key="item.id" :label="item.name" :value="item.name" />
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="重排模型" prop="rerankerModel">
							<template #label>
								重排模型
								<tip content="重排模型，如没有重排模型，则后台使用默认重排算法" />
							</template>
							<el-select v-model="form.rerankerModel" placeholder="请选择重排模型" clearable filterable>
								<el-option v-for="item in rerankerModelList" :key="item.id" :label="item.name" :value="item.name" />
							</el-select>
						</el-form-item>
					</el-col>
				</el-row>

				<el-divider content-position="left">检索配置</el-divider>

				<el-row :gutter="30" class="mb-6">
					<el-col :span="12">
						<el-form-item label="会话轮数" prop="multiRound">
							<template #label>
								会话轮数
								<tip content="会话轮数，0代表不记忆上文会话" />
							</template>
							<el-input-number v-model="form.multiRound" :min="0" :max="5" :step="1" class="w-full" />
						</el-form-item>
					</el-col>

					<el-col :span="12">
						<el-form-item prop="topK">
							<template #label>
								匹配条数
								<tip content="向量数据库匹配最多几条结果" />
							</template>
							<el-input-number v-model="form.topK" :min="1" :max="5" :step="1" class="w-full" />
						</el-form-item>
					</el-col>
				</el-row>

				<el-row :gutter="30" class="mb-6">
					<el-col :span="12">
						<el-form-item prop="fragmentSize">
							<template #label>
								分片值
								<tip content="分片值取决于模型自身能力,理论上分片值越大越准确" />
							</template>
							<el-input-number v-model="form.fragmentSize" :min="500" :max="9999" :step="1" class="w-full" />
						</el-form-item>
					</el-col>

					<el-col :span="12">
						<el-form-item prop="score">
							<template #label>
								匹配率
								<tip content="向量数据库匹配率，建议不低于 50%" />
							</template>
							<el-slider v-model="form.score" :step="10" :min="10" :max="90" :format-tooltip="(value: number) => value + '%'" show-stops />
						</el-form-item>
					</el-col>
				</el-row>

				<el-row :gutter="30" class="mb-6">
					<el-col :span="12">
						<el-form-item prop="emptyLlmFlag">
							<template #label>
								空查询
								<tip content="查询不到结果时，是否调用大模型查询" />
							</template>
							<el-switch v-model="form.emptyLlmFlag" :active-value="'1'" :inactive-value="'0'" />
						</el-form-item>
					</el-col>

					<el-col :span="12" v-if="form.emptyLlmFlag !== '1'">
						<el-form-item prop="emptyDesc">
							<template #label>
								空提示
								<tip content="未匹配的时候，返回的文案" />
							</template>
							<el-input v-model="form.emptyDesc" placeholder="请输入描述" />
						</el-form-item>
					</el-col>
				</el-row>

				<el-divider content-position="left">处理选项</el-divider>

				<el-row :gutter="30" class="mb-6">
					<el-col :span="12">
						<el-form-item label="文档总结" prop="preSummary">
							<el-switch v-model="form.preSummary" :active-value="'1'" :inactive-value="'0'" />
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item prop="aiOcrFlag">
							<template #label>
								AI OCR
								<tip content="PDF、图片等文件，自动进行 AI OCR 识别" />
							</template>
							<el-switch v-model="form.aiOcrFlag" :active-value="'1'" :inactive-value="'0'" />
						</el-form-item>
					</el-col>
				</el-row>

				<el-row :gutter="30" class="mb-6">
					<el-col :span="12">
						<el-form-item label="会话压缩" prop="preCompress">
							<el-switch v-model="form.preCompress" :active-value="'1'" :inactive-value="'0'" />
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item prop="standardFlag">
							<template #label>
								标注数据
								<tip content="使用已经标注修正后的答案，直接返回" />
							</template>
							<el-switch v-model="form.standardFlag" :active-value="'1'" :inactive-value="'0'" />
						</el-form-item>
					</el-col>
				</el-row>
			</div>

			<!-- Security Configuration Tab -->
			<div v-show="activeTab === 'security'" class="px-2">
				<el-divider content-position="left">访问控制</el-divider>

				<el-row :gutter="30" class="mb-6">
					<el-col :span="12">
						<el-form-item label="是否对外" prop="publicFlag">
							<el-switch v-model="form.publicFlag" :active-value="'1'" :inactive-value="'0'" />
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item prop="publicPassword">
							<template #label>
								安全密钥
								<tip content="对外服务，需要用户输入的密码" />
							</template>
							<el-input v-model="form.publicPassword" placeholder="请输入密码" />
						</el-form-item>
					</el-col>
				</el-row>

				<el-row :gutter="30" class="mb-6">
					<el-col :span="24">
						<el-form-item prop="visibleUsers">
							<template #label>
								可见范围
								<tip content="选择可以访问此知识库的用户，如果不选择则全部的用户可访问" />
							</template>
							<org-selector v-model="form.visibleUsers" :type="'user'" :multiple="true" :selectSelf="true" />
						</el-form-item>
					</el-col>
				</el-row>

				<el-divider content-position="left">内容过滤</el-divider>

				<el-row :gutter="30" class="mb-6">
					<el-col :span="12">
						<el-form-item label="敏感词过滤" prop="sensitiveFlag">
							<el-switch v-model="form.sensitiveFlag" :active-value="'1'" :inactive-value="'0'" />
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item prop="sensitiveMsg">
							<template #label>
								提示
								<tip content="命中敏感词，返回的文案" />
							</template>
							<el-input v-model="form.sensitiveMsg" placeholder="请输入描述" />
						</el-form-item>
					</el-col>
				</el-row>

				<el-divider content-position="left">附加信息</el-divider>

				<el-row :gutter="30" class="mb-6">
					<el-col :span="24">
						<el-form-item label="底部信息" prop="footer">
							<el-input type="textarea" maxlength="255" :rows="5" v-model="form.footer" placeholder="聊天框底部的信息，支持 HTML 语法" />
						</el-form-item>
					</el-col>
				</el-row>
			</div>
		</el-form>
		<template #footer>
			<span class="dialog-footer">
				<el-button @click="visible = false">取消</el-button>
				<el-button type="primary" @click="onSubmit" :disabled="loading">确认</el-button>
			</span>
		</template>
	</el-drawer>
</template>

<script setup lang="ts" name="AiDatasetDialog">
// import { useDict } from '/@/hooks/dict'; // Removed as it's unused
import { useMessage } from '/@/hooks/message';
import { getDetails, addObj, putObj, validateName } from '/@/api/knowledge/aiDataset';
import { list as aiModelList } from '/@/api/knowledge/aiModel';
import { list } from '/@/api/knowledge/aiEmbedStore';
import { rule } from '/@/utils/validate';
import UploadImg from '/@/components/Upload/Image.vue';
import OrgSelector from '/@/components/OrgSelector/index.vue';

const emit = defineEmits(['refresh']);

// 定义变量内容
const dataFormRef = ref();
const visible = ref(false);
const loading = ref(false);
const activeTab = ref('basic'); // Added for tab management

// 提交表单数据
const form = reactive({
	id: '',
	name: '',
	avatarUrl: '',
	description: '',
	units: '0',
	fileSize: '0',
	multiRound: 3,
	topK: 2,
	score: 40,
	fragmentSize: 1000,
	sortOrder: 1,
	emptyLlmFlag: '0',
	emptyDesc: '知识库未匹配相关问题，请重新提问',
	sensitiveFlag: '1',
	preSummary: '0',
	preCompress: '0',
	sensitiveMsg: '您输入内容包含敏感词，请重新输入',
	publicFlag: '1',
	publicPassword: '' as string | undefined, // Allow undefined for publicPassword
	standardFlag: '0',
	aiOcrFlag: '1',
	welcomeMsg: '',
	footer: '',
	embeddingModel: '',
	summaryModel: '',
	storeId: '',
	rerankerModel: '',
	visibleUsers: [] as Array<any>, // 可见范围用户列表
});

// 定义校验规则
const dataRules = ref({
	name: [
		{ required: true, message: '知识库名称不能为空', trigger: 'blur' },
		{
			validator: (rule: any, value: any, callback: any) => {
				validateName(rule, value, callback, form.id !== '');
			},
			trigger: 'blur',
		},
	],
	welcomeMsg: [{ required: true, message: '欢迎语不能为空', trigger: 'blur' }],
	multiRound: [{ required: true, message: '多轮会话不能为空', trigger: 'blur' }],
	topK: [{ required: true, message: '多轮会话不能为空', trigger: 'blur' }],
	avatarUrl: [{ required: true, message: '封面不能为空', trigger: 'blur' }],
	emptyDesc: [
		{ validator: rule.overLength, trigger: 'blur' },
		{
			required: true,
			message: '提示不能为空',
			trigger: 'blur',
		},
	],
	sensitiveMsg: [
		{ validator: rule.overLength, trigger: 'blur' },
		{
			required: true,
			message: '提示不能为空',
			trigger: 'blur',
		},
	],
	storeId: [{ required: true, message: '请选择向量库', trigger: 'change' }],
	embeddingModel: [{ required: true, message: '请选择向量模型', trigger: 'change' }],
	summaryModel: [{ required: true, message: '请选择总结模型', trigger: 'change' }],
	rerankerModel: [
		{
			validator: rule.overLength,
			trigger: 'blur',
		},
	],
});

const embeddingModelList = ref<Array<{ id: string; name: string }>>([]);
const chatModelList = ref<Array<{ id: string; name: string }>>([]);
const storeList = ref<Array<{ storeId: string; name: string }>>([]);
const rerankerModelList = ref<Array<{ id: string; name: string }>>([]);

// Modify the function to fetch AI models based on modelType
async function loadAiModelList() {
	try {
		const [embeddingResponse, chatResponse, rerankerResponse] = await Promise.all([
			aiModelList({ modelType: 'Embedding' }),
			aiModelList({ modelType: ['Chat', 'Reason'] }),
			aiModelList({ modelType: 'Reranker' }),
		]);

		embeddingModelList.value = embeddingResponse.data.map((item: any) => ({
			id: item.id,
			name: item.name,
		}));

		chatModelList.value = chatResponse.data.map((item: any) => ({
			id: item.id,
			name: item.name,
		}));

		rerankerModelList.value = rerankerResponse.data.map((item: any) => ({
			id: item.id,
			name: item.name,
		}));

		// Set default values if lists are not empty
		if (embeddingModelList.value.length > 0 && !form.embeddingModel) {
			form.embeddingModel = embeddingModelList.value[0].name;
		}
		if (chatModelList.value.length > 0 && !form.summaryModel) {
			form.summaryModel = chatModelList.value[0].name;
		}
		if (rerankerModelList.value.length > 0 && !form.rerankerModel) {
			form.rerankerModel = rerankerModelList.value[0].name;
		}
	} catch (error) {
		useMessage().error('加载AI模型列表失败');
	}
}

// 初始化表单数据
const getAiDatasetData = (id: string) => {
	// 获取数据
	loading.value = true;
	getDetails({ id })
		.then((res: any) => {
			Object.assign(form, res.data);
		})
		.finally(() => {
			loading.value = false;
		});
};

// Modify the openDialog function
const openDialog = async (id: string) => {
	visible.value = true;
	form.id = '';

	// Reset form data
	nextTick(() => {
		dataFormRef.value?.resetFields();
	});

	// Load the collection list and AI model list
	await loadAiModelList();

	// 初始化向量库列表
	const { data } = await list();
	storeList.value = data;

	// Set default value for storeId if list is not empty
	if (storeList.value.length > 0 && !form.storeId) {
		form.storeId = storeList.value[0].storeId;
	}

	// Get aiDataset information
	if (id) {
		form.id = id;
		getAiDatasetData(id);
	} else {
		// Set default values for new records
		if (embeddingModelList.value.length > 0) {
			form.embeddingModel = embeddingModelList.value[0].name;
		}
		if (chatModelList.value.length > 0) {
			form.summaryModel = chatModelList.value[0].name;
		}
		if (rerankerModelList.value.length > 0) {
			form.rerankerModel = rerankerModelList.value[0].name;
		}
	}
};

// 提交
const onSubmit = async () => {
	try {
		// 步骤 1: 异步验证整个表单
		// dataFormRef.value.validate() 会返回一个 Promise
		// 如果验证失败，它会抛出错误，该错误将被下面的 catch 块捕获
		await dataFormRef.value.validate();

		// 步骤 2: 如果验证通过，则继续执行提交逻辑
		// 特殊处理：如果存在 ID (即为编辑模式) 且密码字段包含 '**' (表示未修改),
		// 则将密码设置为空，避免将占位符提交到后端
		if (form.id && form.publicPassword?.includes('**')) {
			form.publicPassword = undefined;
		}

		loading.value = true; // 开始加载状态，禁用提交按钮等
		// 根据是否存在 form.id 来判断是更新 (putObj) 还是新增 (addObj)
		form.id ? await putObj(form) : await addObj(form);

		// 操作成功提示
		useMessage().success(form.id ? '修改成功' : '添加成功');
		visible.value = false; // 关闭抽屉（或弹窗）
		emit('refresh'); // 触发 'refresh' 事件，通知父组件刷新列表数据
	} catch (invalidFields: any) {
		// 步骤 3: 处理表单验证失败的情况
		// invalidFields 对象包含了所有未通过验证的字段及其错误信息
		// Element Plus 的 validate 方法在验证失败时会 reject 一个包含错误字段的对象
		if (invalidFields && Object.keys(invalidFields).length > 0) {
			const errorFields: string[] = Object.keys(invalidFields); // 获取所有验证失败的字段名

			// 定义各选项卡包含的字段，用于定位错误字段所在的选项卡
			const tabFields: Record<string, string[]> = {
				basic: ['name', 'avatarUrl', 'welcomeMsg', 'sortOrder'], // 基础配置选项卡下的字段
				advanced: [
					'storeId',
					'embeddingModel',
					'summaryModel',
					'multiRound',
					'topK',
					'fragmentSize',
					'score',
					'emptyLlmFlag',
					'emptyDesc',
					'preSummary',
					'preCompress',
					'aiOcrFlag',
					'standardFlag',
					'rerankerModel',
				], // 高级配置选项卡下的字段
				security: ['publicFlag', 'publicPassword', 'visibleUsers', 'sensitiveFlag', 'sensitiveMsg', 'footer'], // 安全配置选项卡下的字段
			};

			// 遍历 tabFields 来确定哪个选项卡包含第一个出错的字段
			for (const [tab, fieldsInTab] of Object.entries(tabFields)) {
				// .some() 方法检查 errorFields 数组中是否有任何一个字段存在于当前 fieldsInTab 数组中
				if (errorFields.some((errorField: string) => fieldsInTab.includes(errorField))) {
					activeTab.value = tab; // 如果找到，则切换到该选项卡
					break; // 找到第一个错误字段所在的选项卡后，停止遍历
				}
			}
		}
		// 如果验证失败，错误被捕获，提交过程在此处停止。
		// 函数将继续执行 finally 块。
	} finally {
		// 步骤 4: 无论提交成功还是失败，最后都会执行 finally 块
		loading.value = false; // 结束加载状态
	}
};

// 暴露变量
defineExpose({
	openDialog,
});
</script>
