<script setup lang="ts">
import type { Ref } from "vue";
import { computed, onMounted, onUnmounted, ref, watch, h } from "vue";
import { useRoute, useRouter } from "vue-router";
import { storeToRefs } from "pinia";
import {
	NAutoComplete,
	NButton,
	NInput,
	useDialog,
	useMessage,
	NAvatar,
	NModal,
	NCard,
	NImage,
} from "naive-ui";
import html2canvas from "html2canvas";
import { Message } from "./components";
import { useScroll } from "./hooks/useScroll";
import { useChat } from "./hooks/useChat";
import { useUsingContext } from "./hooks/useUsingContext";
import { getGpts } from "@/api/chatmsg";
import { SvgIcon } from "@/components/common";
import { useBasicLayout } from "@/hooks/useBasicLayout";
import {
	gptConfigStore,
	gptsUlistStore,
	homeStore,
	useChatStore,
	usePromptStore,
	useAppStore,
} from "@/store";
import {
	chatSetting,
	fetchChatAPIProcess,
	gptsType,
	mlog,
	myFetch,
	my2Fetch,
} from "@/api";
import { t } from "@/locales";
import drawListVue from "../mj/drawList.vue";
import aiGPT from "../mj/aiGpt.vue";
import AiSiderInput from "../mj/aiSiderInput.vue";
import aiGptInput from "../mj/aiGptInput.vue";
import { getNotice, readNotice, getInform } from "@/api/notice";
import to from "await-to-js";

let controller = new AbortController();

const openLongReply = import.meta.env.VITE_GLOB_OPEN_LONG_REPLY === "true";

const route = useRoute();
const dialog = useDialog();
const ms = useMessage();
const router = useRouter();
const chatStore = useChatStore();
// const href = window.location.href.split('#')[0]

const href = window.location.hostname;
const { isMobile } = useBasicLayout();
const { addChat, updateChat, updateChatSome, getChatByUuidAndIndex } =
	useChat();
const { scrollRef, scrollToBottom, scrollToBottomIfAtBottom } = useScroll();
const { usingContext, toggleUsingContext } = useUsingContext();

const { uuid } = route.params as { uuid: string };

const dataSources = computed(() => chatStore.getChatByUuid(+uuid));
const conversationList = computed(() =>
	dataSources.value.filter(
		(item) => !item.inversion && !!item.conversationOptions
	)
);

const prompt = ref<string>("");
const loading = ref<boolean>(false);
const inputRef = ref<Ref | null>(null);

// 添加PromptStore
const promptStore = usePromptStore();

// 使用storeToRefs，保证store修改后，联想部分能够重新渲染
const { promptList: promptTemplate } = storeToRefs<any>(promptStore);

const appStore = useAppStore();
const isChat = computed(() => appStore.isChat);

// 未知原因刷新页面，loading 状态不会重置，手动重置
dataSources.value.forEach((item, index) => {
	if (item.loading) updateChatSome(+uuid, index, { loading: false });
});

function handleSubmit() {
	//onConversation() //把这个放到aiGpt
	let message = prompt.value;
	if (!message || message.trim() === "") return;
	if (loading.value) return;
	loading.value = true;
	homeStore.setMyData({
		act: "gpt.submit",
		actData: { prompt: prompt.value, uuid },
	});
	prompt.value = "";
}

async function onConversation() {
	let message = prompt.value;

	if (loading.value) return;

	if (!message || message.trim() === "") return;

	controller = new AbortController();

	addChat(+uuid, {
		dateTime: new Date().toLocaleString(),
		text: message,
		inversion: true,
		error: false,
		conversationOptions: null,
		requestOptions: { prompt: message, options: null },
	});
	scrollToBottom();

	loading.value = true;
	prompt.value = "";

	let options: Chat.ConversationRequest = {};
	const lastContext =
		conversationList.value[conversationList.value.length - 1]
			?.conversationOptions;

	if (lastContext && usingContext.value) options = { ...lastContext };

	addChat(+uuid, {
		dateTime: new Date().toLocaleString(),
		text: "思考中",
		loading: true,
		inversion: false,
		error: false,
		conversationOptions: null,
		requestOptions: { prompt: message, options: { ...options } },
	});
	scrollToBottom();

	try {
		let lastText = "";
		const fetchChatAPIOnce = async () => {
			await fetchChatAPIProcess<Chat.ConversationResponse>({
				prompt: message,
				options,
				signal: controller.signal,
				onDownloadProgress: ({ event }) => {
					const xhr = event.target;
					const { responseText } = xhr;
					// Always process the final line
					const lastIndex = responseText.lastIndexOf(
						"\n",
						responseText.length - 2
					);
					let chunk = responseText;
					if (lastIndex !== -1) chunk = responseText.substring(lastIndex);
					try {
						const data = JSON.parse(chunk);
						updateChat(+uuid, dataSources.value.length - 1, {
							dateTime: new Date().toLocaleString(),
							text: lastText + (data.text ?? ""),
							inversion: false,
							error: false,
							loading: true,
							conversationOptions: {
								conversationId: data.conversationId,
								parentMessageId: data.id,
							},
							requestOptions: { prompt: message, options: { ...options } },
						});

						if (
							openLongReply &&
							data.detail.choices[0].finish_reason === "length"
						) {
							options.parentMessageId = data.id;
							lastText = data.text;
							message = "";
							return fetchChatAPIOnce();
						}

						scrollToBottomIfAtBottom();
					} catch (error) {
						//
					}
				},
			});
			updateChatSome(+uuid, dataSources.value.length - 1, { loading: false });
		};

		await fetchChatAPIOnce();
	} catch (error: any) {
		const errorMessage = error?.message ?? t("common.wrong");

		if (error.message === "canceled") {
			updateChatSome(+uuid, dataSources.value.length - 1, {
				loading: false,
			});
			scrollToBottomIfAtBottom();
			return;
		}

		const currentChat = getChatByUuidAndIndex(
			+uuid,
			dataSources.value.length - 1
		);

		if (currentChat?.text && currentChat.text !== "") {
			updateChatSome(+uuid, dataSources.value.length - 1, {
				text: `${currentChat.text}\n[${errorMessage}]`,
				error: false,
				loading: false,
			});
			return;
		}

		updateChat(+uuid, dataSources.value.length - 1, {
			dateTime: new Date().toLocaleString(),
			text: errorMessage,
			inversion: false,
			error: true,
			loading: false,
			conversationOptions: null,
			requestOptions: { prompt: message, options: { ...options } },
		});
		scrollToBottomIfAtBottom();
	} finally {
		loading.value = false;
	}
}

async function onRegenerate(index: number) {
	if (loading.value) return;

	controller = new AbortController();

	const { requestOptions } = dataSources.value[index];

	let message = requestOptions?.prompt ?? "";

	let options: Chat.ConversationRequest = {};

	if (requestOptions.options) options = { ...requestOptions.options };

	loading.value = true;

	updateChat(+uuid, index, {
		dateTime: new Date().toLocaleString(),
		text: "",
		inversion: false,
		error: false,
		loading: true,
		conversationOptions: null,
		requestOptions: { prompt: message, options: { ...options } },
	});

	try {
		let lastText = "";
		const fetchChatAPIOnce = async () => {
			await fetchChatAPIProcess<Chat.ConversationResponse>({
				prompt: message,
				options,
				signal: controller.signal,
				onDownloadProgress: ({ event }) => {
					const xhr = event.target;
					const { responseText } = xhr;
					// Always process the final line
					const lastIndex = responseText.lastIndexOf(
						"\n",
						responseText.length - 2
					);
					let chunk = responseText;
					if (lastIndex !== -1) chunk = responseText.substring(lastIndex);
					try {
						const data = JSON.parse(chunk);
						updateChat(+uuid, index, {
							dateTime: new Date().toLocaleString(),
							text: lastText + (data.text ?? ""),
							inversion: false,
							error: false,
							loading: true,
							conversationOptions: {
								conversationId: data.conversationId,
								parentMessageId: data.id,
							},
							requestOptions: { prompt: message, options: { ...options } },
						});

						if (
							openLongReply &&
							data.detail.choices[0].finish_reason === "length"
						) {
							options.parentMessageId = data.id;
							lastText = data.text;
							message = "";
							return fetchChatAPIOnce();
						}
					} catch (error) {
						//
					}
				},
			});
			updateChatSome(+uuid, index, { loading: false });
		};
		await fetchChatAPIOnce();
	} catch (error: any) {
		if (error.message === "canceled") {
			updateChatSome(+uuid, index, {
				loading: false,
			});
			return;
		}

		const errorMessage = error?.message ?? t("common.wrong");

		updateChat(+uuid, index, {
			dateTime: new Date().toLocaleString(),
			text: errorMessage,
			inversion: false,
			error: true,
			loading: false,
			conversationOptions: null,
			requestOptions: { prompt: message, options: { ...options } },
		});
	} finally {
		loading.value = false;
	}
}

function handleExport() {
	if (loading.value) return;

	const d = dialog.warning({
		title: t("chat.exportImage"),
		content: t("chat.exportImageConfirm"),
		positiveText: t("common.yes"),
		negativeText: t("common.no"),
		onPositiveClick: async () => {
			try {
				d.loading = true;
				const ele = document.getElementById("image-wrapper");
				const canvas = await html2canvas(ele as HTMLDivElement, {
					useCORS: true,
				});
				const imgUrl = canvas.toDataURL("image/png");
				const tempLink = document.createElement("a");
				tempLink.style.display = "none";
				tempLink.href = imgUrl;
				tempLink.setAttribute("download", "chat-shot.png");
				if (typeof tempLink.download === "undefined")
					tempLink.setAttribute("target", "_blank");

				document.body.appendChild(tempLink);
				tempLink.click();
				document.body.removeChild(tempLink);
				window.URL.revokeObjectURL(imgUrl);
				d.loading = false;
				ms.success(t("chat.exportSuccess"));
				Promise.resolve();
			} catch (error: any) {
				ms.error(t("chat.exportFailed"));
			} finally {
				d.loading = false;
			}
		},
	});
}

function handleDelete(index: number) {
	if (loading.value) return;

	dialog.warning({
		title: t("chat.deleteMessage"),
		content: t("chat.deleteMessageConfirm"),
		positiveText: t("common.yes"),
		negativeText: t("common.no"),
		onPositiveClick: () => {
			chatStore.deleteChatByUuid(+uuid, index);
		},
	});
}

function handleClear() {
	if (loading.value) return;

	dialog.warning({
		title: t("chat.clearChat"),
		content: t("chat.clearChatConfirm"),
		positiveText: t("common.yes"),
		negativeText: t("common.no"),
		onPositiveClick: () => {
			chatStore.clearChatByUuid(+uuid);
		},
	});
}

function handleEnter(event: KeyboardEvent) {
	if (!isMobile.value) {
		if (event.key === "Enter" && !event.shiftKey) {
			event.preventDefault();
			handleSubmit();
		}
	} else {
		if (event.key === "Enter" && event.ctrlKey) {
			event.preventDefault();
			handleSubmit();
		}
	}
}

function handleStop() {
	if (loading.value) {
		homeStore.setMyData({ act: "abort" });
		controller.abort();
		loading.value = false;
	}
}
function handleEdit(index: number) {
	if (loading.value) return;

	const editedMessage = ref(dataSources.value[index].text.slice());

	const inputNode = () => {
		return h(NInput, {
			value: editedMessage.value,
			type: "textarea",
			autosize: { minRows: 1, maxRows: 12 },
			showCount: true,
			"onUpdate:value": (v: string) => {
				editedMessage.value = v;
			},
		});
	};

	dialog.warning({
		title: t("common.edit"),
		style: { width: "1000px" },
		content: inputNode,
		positiveText: t("common.yes"),
		negativeText: t("common.no"),
		onPositiveClick: () => {
			updateChatSome(+uuid, index, { text: editedMessage.value });
		},
	});
}

// 可优化部分
// 搜索选项计算，这里使用value作为索引项，所以当出现重复value时渲染异常(多项同时出现选中效果)
// 理想状态下其实应该是key作为索引项,但官方的renderOption会出现问题，所以就需要value反renderLabel实现
const searchOptions = computed(() => {
	if (prompt.value.startsWith("/")) {
		const abc = promptTemplate.value
			.filter((item: { key: string }) =>
				item.key.toLowerCase().includes(prompt.value.substring(1).toLowerCase())
			)
			.map((obj: { value: any }) => {
				return {
					label: obj.value,
					value: obj.value,
				};
			});
		mlog("搜索选项", abc);
		return abc;
	} else if (prompt.value == "@") {
		const abc = gptsUlistStore.myData.slice(0, 10).map((v: gptsType) => {
			return {
				label: v.info,
				gpts: v,
				value: v.gid,
			};
		});
		return abc;
	} else {
		return [];
	}
});

const goUseGpts = async (item: gptsType) => {
	const saveObj = { model: `${item.gid}`, gpts: item };
	gptConfigStore.setMyData(saveObj);
	if (chatStore.active) {
		//保存到对话框
		const chatSet = new chatSetting(chatStore.active);
		if (chatSet.findIndex() > -1) chatSet.save(saveObj);
	}
	ms.success(t("mjchat.success2"));
	// const gptUrl= `https://gpts.ddaiai.com/open/gptsapi/use`;
	// myFetch(gptUrl,item );

	mlog("go local ", homeStore.myData.local);
	if (homeStore.myData.local !== "Chat")
		router.replace({ name: "Chat", params: { uuid: chatStore.active } });

	gptsUlistStore.setMyData(item);
};

// value反渲染key
const renderOption = (option: { label: string; gpts?: gptsType }) => {
	if (prompt.value == "@") {
		//return [ h( NAvatar,{src:'https://cos.aitutu.cc/gpts/gpt4all.jpg',size:"small",round:true}),option.label ]
		return [
			h(
				"div",
				{
					class: "flex justify-start items-center",
					onclick: () => {
						if (option.gpts) goUseGpts(option.gpts);
						prompt.value = "";
						setTimeout(() => (prompt.value = ""), 80);
					},
				},
				[
					h(NAvatar, {
						src: option.gpts?.logo,
						"fallback-src": "https://cos.aitutu.cc/gpts/3.5net.png",
						size: "small",
						round: true,
						class: "w-8 h-8",
					}),
					h("span", { class: "pl-1" }, option.gpts?.name),
					h(
						"span",
						{ class: "line-clamp-1 flex-1 pl-1 opacity-50" },
						option.label
					),
				]
			),
		];
	}
	for (const i of promptTemplate.value) {
		if (i.value === option.label) return [i.key];
	}
	return [];
};

const placeholder = computed(() => {
	if (isMobile.value) return t("chat.placeholderMobile");
	return t("chat.placeholder");
});

const buttonDisabled = computed(() => {
	return loading.value || !prompt.value || prompt.value.trim() === "";
});

const footerClass = computed(() => {
	let classes = ["p-4"];
	if (isMobile.value)
		classes = ["sticky", "left-0", "bottom-0", "right-0", "p-2", "pr-3"]; //, 'overflow-hidden'
	return classes;
});

onMounted(() => {
	scrollToBottom();
	if (inputRef.value && !isMobile.value) inputRef.value?.focus();
	// 查询公告信息
	selectNotice();
	// 查询通知信息
	selectInform();
});

onUnmounted(() => {
	if (loading.value) controller.abort();
	homeStore.setMyData({ isLoader: false });
});

const local = computed(() => homeStore.myData.local);
watch(
	() => homeStore.myData.act,
	(n) => {
		if (n == "draw") scrollToBottom();
		if (n == "scrollToBottom") scrollToBottom();
		if (n == "scrollToBottomIfAtBottom") scrollToBottomIfAtBottom();
		if (n == "gpt.submit" || n == "gpt.resubmit") {
			loading.value = true;
		}
		if (n == "stopLoading") {
			loading.value = false;
		}
	}
);
const st = ref({ inputme: true });

watch(
	() => loading.value,
	(n) => homeStore.setMyData({ isLoader: n })
);

const ychat = computed(() => {
	let text = prompt.value;
	if (loading.value) text = "";
	else {
		scrollToBottomIfAtBottom();
	}
	return { text, dateTime: t("chat.preview") } as Chat.Chat;
});

const showModal = ref(false);
const modalContent = ref("<h2>暂无内容</h2>");
const informContent = ref([]);
const noticeId = ref("");
async function selectNotice() {
	const [err, result] = await to(getNotice());
	console.log("result?.data", result?.data);
	if (result?.data) {
		showModal.value = true;
		noticeId.value = result.data.noticeId;
		modalContent.value = result.data.noticeContent;
	}
}
async function selectInform() {
	const [err, result] = await to(getInform());
	if (result?.rows) {
		informContent.value = result.rows.length ? result.rows : [];
	}
}

async function handleClose() {
	await to(readNotice(noticeId.value));
}
const gptsList = ref<gptsType[]>([]);
const gptsFilterList = ref<gptsType[]>([]);
const getRandowNum = (Min: number, Max: number): number => {
	const Range = Max - Min + 1;
	const Rand = Math.random();
	return Min + Math.floor(Rand * Range);
};
const load = async () => {
	// const gptUrl= homeStore.myData.session.gptUrl?  homeStore.myData.session.gptUrl :'';
	// mlog('load',gptUrl );
	//  let d;
	// if( homeStore.myData.session.gptUrl ){
	//    d = await my2Fetch( homeStore.myData.session.gptUrl  );
	// }else {

	//     d = await myFetch('https://gpts.ddaiai.com/open/gpts');
	// }

	const params = { pageNum: 1, pageSize: 20 };
	const [err, result] = await to(getGpts(params));
	if (err) {
		console.log("err===", err);
	} else {
		gptsList.value = result.rows as unknown as gptsType[];
	}

	// gptsList.value = d.gpts as gptsType[];
	if (gptsList.value.length && gptsList.value.length > 3) {
		gptsFilterList.value = gptsList.value.slice(0, 4);
	}
};
const refresh = () => {
	gptsFilterList.value = [];
	let num = gptsList.value[getRandowNum(0, gptsList.value.length - 1)];
	let num1 = gptsList.value[getRandowNum(0, gptsList.value.length - 1)];
	let num2 = gptsList.value[getRandowNum(0, gptsList.value.length - 1)];
	let num3 = gptsList.value[getRandowNum(0, gptsList.value.length - 1)];
	let arr = [num, num1, num2, num3];
	if (Array.from(new Set(arr)).length != 4) {
		refresh();
		return;
	}
	gptsFilterList.value = [num, num1, num2, num3];
};
load();
</script>

<template>
	<NModal
		v-model:show="showModal"
		closable
		@on-after-leave=""
		:mask-closable="false"
		preset="dialog"
		title="公告详情"
		positive-text="我已知晓"
		@positive-click="handleClose"
	>
		<div v-html="modalContent"></div>
	</NModal>

	<div
		class="flex flex-col w-full h-full chat-content"
		:class="[isMobile ? '' : 'chat-content-noMobile']"
	>
		<!-- v-if="isMobile" -->
		<!-- <HeaderComponent
      :haveData="!!dataSources.length"
      :using-context="usingContext"
      @export="handleExport"
      @handle-clear="handleClear"
    /> -->

		<main class="flex-1 overflow-hidden">
			<template v-if="gptConfigStore.myData.kid">
				<div class="flex mt-4 text-neutral-300 chat-header">
					<SvgIcon icon="material-symbols:book" class="mr-1 text-2xl"></SvgIcon>
					<span>{{ gptConfigStore.myData.kName }}</span>
				</div>
			</template>

			<div
				id="scrollRef"
				ref="scrollRef"
				class="h-full overflow-hidden overflow-y-auto"
			>
				<div
					id="image-wrapper"
					class="w-full max-w-screen-xl m-auto dark:bg-[#101014]"
					:class="[isMobile ? 'p-2' : 'p-4']"
				>
					<template v-if="!dataSources.length">
						<div
							v-if="homeStore.myData.session.notify"
							v-html="homeStore.myData.session.notify"
							class="text-neutral-300 mt-4"
						></div>
						<div class="gpts-box" v-else>
							<h1>{{ href }}</h1>
							<div
								class="annou"
								v-if="informContent.length"
								:style="{ 'margin-bottom': isMobile ? '15px' : '30px' }"
							>
								<div class="ai-icon">
									<IconSvg
										icon="chatGPT"
										:width="isMobile ? '32px' : '64px'"
										:height="isMobile ? '32px' : '64px'"
									></IconSvg>
								</div>
								<div
									class="text"
									:style="{ padding: isMobile ? '22px 10px' : '22px 68px' }"
								>
									<p class="title">{{ t("chat.annouce") }}</p>
									<!-- <p v-for="(item,index) in t('chat.annouceContent').split(';')" :key="index">{{ item }}</p> -->
									<div
										v-for="(item, index) in informContent.slice(0, 1)"
										:key="index"
									>
										<!-- <p style="margin-top: 10px; font-size: 18px">{{ item.noticeTitle }}</p> -->
										<div v-html="item.noticeContent"></div>
									</div>
								</div>
							</div>
							<div class="help" v-if="gptsFilterList && gptsFilterList.length">
								<div class="ai-icon">
									<IconSvg
										icon="chatGPT"
										:width="isMobile ? '32px' : '64px'"
										:height="isMobile ? '32px' : '64px'"
									></IconSvg>
								</div>
								<div
									class="text"
									:style="{
										padding: isMobile ? '22px 10px' : '22px 68px',
										'font-size': isMobile ? '14px' : '16px',
										'line-height': isMobile ? '20px' : '28px',
									}"
								>
									<p class="title">
										{{ t("chat.helpTitle") }}
									</p>
									<p
										v-for="(item, index) in t('chat.helpcontent').split(';')"
										:key="index"
									>
										{{ item }}
									</p>
									<div class="gpts-list">
										<div class="refresh" @click="refresh">
											<IconSvg icon="refresh"></IconSvg>&nbsp;{{
												t("chat.refresh")
											}}
										</div>
										<div
											v-for="v in gptsFilterList"
											:key="v.name"
											class="gpts-item"
											:style="{
												width: isMobile ? '100%' : 'calc(50% - 20px)',
												marginRight: '20px',
												padding: isMobile ? '5px 8px' : '14px 10px',
												'margin-bottom': isMobile ? '8px' : '20px',
											}"
										>
											<NImage
												:src="v.logo"
												:preview-disabled="true"
												lazy
												class="group-hover:scale-[130%] duration-300 shrink-0 overflow-hidden bg-base object-cover rounded-full bc-avatar w-[80px] h-[80px]"
												:style="{
													width: isMobile ? '23px' : '46px',
													height: isMobile ? '23px' : '46px',
												}"
											>
												<template #placeholder>
													<div
														class="w-full h-full justify-center items-center flex"
													>
														<SvgIcon
															icon="line-md:downloading-loop"
															class="text-[60px] text-green-300"
														></SvgIcon>
													</div>
												</template>
											</NImage>
											<div
												:style="{
													width: `calc(100% - ${isMobile ? '43px' : '66px'})`,
													float: 'left',
													marginLeft: '10px',
												}"
											>
												<p class="info" :title="v.info">{{ v.info }}</p>
												<p @click="goUseGpts(v)" class="name">
													{{ t("chat.used") }} {{ v.name }}
												</p>
											</div>
										</div>
									</div>
								</div>
							</div>
						</div>
						<!-- <div class="flex items-center justify-center mt-4 text-center text-neutral-300" v-else>
              <SvgIcon icon="ri:bubble-chart-fill" class="mr-2 text-3xl" />
              <span>Aha~</span>
            </div> -->
					</template>

					<template v-else>
						<div>
							<Message
								v-for="(item, index) of dataSources"
								:key="index"
								:date-time="item.dateTime"
								:text="item.text"
								:inversion="item.inversion"
								:error="item.error"
								:loading="item.loading"
								@regenerate="onRegenerate(index)"
								@delete="handleDelete(index)"
								@edit="handleEdit(index)"
								:chat="item"
								:index="index"
							/>
							<Message
								v-if="ychat.text && !homeStore.myData.session.isCloseMdPreview"
								:key="dataSources.length"
								:inversion="true"
								:date-time="$t('mj.typing')"
								:chat="ychat"
								:text="ychat.text"
								:index="dataSources.length"
							/>
							<div class="sticky bottom-0 left-0 flex justify-center">
								<NButton v-if="loading" type="warning" @click="handleStop">
									<template #icon>
										<SvgIcon icon="ri:stop-circle-line" />
									</template>
									{{ t("common.stopResponding") }}
								</NButton>
							</div>
						</div>
					</template>
				</div>
			</div>
		</main>

		<footer :class="footerClass" class="footer-content" v-if="local !== 'draw'">
			<div class="w-full max-w-screen-xl m-auto">
				<aiGptInput
					@handle-clear="handleClear"
					@export="handleExport"
					v-if="
						['gpt-4o-mini', 'gpt-3.5-turbo-16k'].indexOf(
							gptConfigStore.myData.model
						) > -1 || st.inputme
					"
					v-model:modelValue="prompt"
					:disabled="buttonDisabled"
					:searchOptions="searchOptions"
					:renderOption="renderOption"
				/>
				<div class="flex items-center justify-between space-x-2" v-else>
					<!--
          <HoverButton v-if="!isMobile" @click="handleClear">
            <span class="text-xl text-[#4f555e] dark:text-white">
              <SvgIcon icon="ri:delete-bin-line" />
            </span>
          </HoverButton>
          <HoverButton v-if="!isMobile" @click="handleExport">
            <span class="text-xl text-[#4f555e] dark:text-white">
              <SvgIcon icon="ri:download-2-line" />
            </span>
          </HoverButton>
          <HoverButton @click="toggleUsingContext">
            <span class="text-xl" :class="{ 'text-[#4b9e5f]': usingContext, 'text-[#a8071a]': !usingContext }">
              <SvgIcon icon="ri:chat-history-line" />
            </span>
          </HoverButton>
          -->

					<NAutoComplete
						v-model:value="prompt"
						:options="searchOptions"
						:render-label="renderOption"
					>
						<template #default="{ handleInput, handleBlur, handleFocus }">
							<NInput
								ref="inputRef"
								v-model:value="prompt"
								type="textarea"
								:placeholder="placeholder"
								:autosize="{ minRows: 1, maxRows: isMobile ? 4 : 8 }"
								@input="handleInput"
								@focus="handleFocus"
								@blur="handleBlur"
								@keypress="handleEnter"
							/>
						</template>
					</NAutoComplete>
					<NButton
						type="primary"
						:disabled="buttonDisabled"
						@click="handleSubmit"
					>
						<template #icon>
							<span class="dark:text-black">
								<SvgIcon icon="ri:send-plane-fill" />
							</span>
						</template>
					</NButton>
				</div>
			</div>
		</footer>
	</div>

	<drawListVue />
	<aiGPT @finished="loading = false" />
	<AiSiderInput v-if="isMobile" :button-disabled="false" />
</template>
