import { useCallback, useEffect } from "react";

import IconChatAdd from "virtual:icons/mdi/chat-add";
import IconClose from "virtual:icons/mdi/close";

import GetStarted from "./GetStarted";
import GetStartedFooter from "./GetStartedFooter";
import Input from "./Input";
import Layout from "./Layout";
import MessagesList from "./MessagesList";
import TopicSelector from "./TopicSelector";
import { useChat, useI18n, useOptions } from "../composables";
import { chatEventBus } from "../event-buses";

import "./Chat.scss";

function emitScrollToBottom() {
	if (typeof queueMicrotask === "function") {
		queueMicrotask(() => chatEventBus.emit("scrollToBottom"));
		return;
	}

	setTimeout(() => chatEventBus.emit("scrollToBottom"), 0);
}

export default function Chat() {
	const { t } = useI18n();
	const { options } = useOptions();
	const {
		messages,
		initialMessages,
		currentSessionId,
		loadPreviousSession,
		startNewSession,
		isTopicSelectionPending,
	} = useChat();

	const shouldShowWelcomeScreen =
		!currentSessionId && options.showWelcomeScreen;

	const handleGetStarted = useCallback(async () => {
		if (!startNewSession) return;
		await startNewSession();
		emitScrollToBottom();
	}, [startNewSession]);

	const handleNewChat = useCallback(async () => {
		if (!startNewSession) return;
		await startNewSession();
		emitScrollToBottom();
	}, [startNewSession]);

	useEffect(() => {
		let cancelled = false;

		const initialize = async () => {
			let hasRestoredSession = false;

			if (loadPreviousSession && !currentSessionId) {
				hasRestoredSession = await loadPreviousSession();
				if (!cancelled) {
					emitScrollToBottom();
				}
			}

			if (
				!options.showWelcomeScreen &&
				!hasRestoredSession &&
				!currentSessionId &&
				startNewSession
			) {
				await startNewSession();
				if (!cancelled) {
					emitScrollToBottom();
				}
			}
		};

		void initialize();
		return () => {
			cancelled = true;
		};
	}, [
		currentSessionId,
		loadPreviousSession,
		options.showWelcomeScreen,
		startNewSession,
	]);

	const closeChat = () => {
		chatEventBus.emit("close");
	};

	return (
		<div className="chat-wrapper">
			<Layout
				header={
					<div className="chat-heading">
						<div>
							<h1>{t("title")}</h1>
							{t("subtitle") && <p>{t("subtitle")}</p>}
						</div>
						<div className="chat-heading-actions">
							<button
								className="chat-new-button"
								type="button"
								title={t("newChatButtonTooltip")}
								aria-label={t("newChatButtonTooltip")}
								onClick={handleNewChat}
							>
								<IconChatAdd height="18" width="18" />
							</button>
							<button
								className="chat-close-button"
								type="button"
								title={t("closeButtonTooltip")}
								aria-label={t("closeButtonTooltip")}
								onClick={closeChat}
							>
								<IconClose height="18" width="18" />
							</button>
						</div>
					</div>
				}
				footer={currentSessionId ? <Input /> : <GetStartedFooter />}
			>
				{shouldShowWelcomeScreen ? (
					<GetStarted onClick={handleGetStarted} />
				) : (
					<MessagesList
						messages={messages}
						initialMessages={initialMessages}
						renderBeforeMessages={
							isTopicSelectionPending ? <TopicSelector /> : null
						}
					/>
				)}
			</Layout>
		</div>
	);
}
