import { useContext, useEffect, useMemo, useState } from "react";
import { ApiContext } from "../../context";
import { ColorTheme } from "../../types/shared-types";
import { Spinner } from "../spinner";

interface ThemePreviewProps {
	theme: ColorTheme;
	loading?: boolean;
}

export function ThemePreview({
	theme,
	loading,
}: ThemePreviewProps): React.JSX.Element {
	const { colorize } = useContext(ApiContext);

	const [codeHtml, setCodeHtml] = useState<TrustedHTML | null>(null);

	useEffect(() => {
		(async function () {
			const trustedHtml = await colorize([
				"function x() {var y = 10;}",
				"// code comment",
			]);
			setCodeHtml(trustedHtml);
		})();
	}, []);

	const parentClass = useMemo(
		() => `p${Math.floor(Math.random() * 1000000)}`,
		[]
	);

	const tokenCSS = useMemo(() => {
		return theme.getTokenCSS(parentClass);
	}, [theme]);

	const background = theme.getColor("background");
	const backgroundGradientStart =
		theme.getColor("background.gradientStart") || background;
	const backgroundGradientEnd =
		theme.getColor("background.gradientEnd") || background;

	const editorBackground = theme.getColor("editor.background");
	const tabActiveBackground = theme.getColor("tab.activeBackground");
	const tabActiveForeground = theme.getColor("tab.activeForeground");
	const tabActiveBorder = theme.getColor("tab.activeBorder") || "black";

	const listInactiveSelectionBackground = theme.getColor(
		"list.inactiveSelectionBackground"
	);
	const listActiveSelectionBackground = theme.getColor(
		"list.activeSelectionBackground"
	);
	const badgeForeground = theme.getColor("badge.foreground");
	const foreground = theme.getColor("foreground");

	const buttonBackground = theme.getColor("button.background");
	const buttonGradient = theme.getColor("button.gradient") || "transparent";

	const editorGroupBorder = theme.getColor("editorGroup.border");

	return (
		<div
			className="w-45 rounded-xl border-1 overflow-hidden relative"
			style={{
				background: `linear-gradient(to bottom, ${backgroundGradientStart}, ${backgroundGradientEnd})`,
				borderColor: editorBackground,
			}}
		>
			<div
				className="h-5 w-fit flex flex-row items-center gap-1 p-1.5 rounded-t-sm"
				style={{
					backgroundColor: tabActiveBackground,
					borderBottom: `1px solid ${tabActiveBorder}`,
				}}
			>
				<div
					className="h-1 rounded-xs w-14 opacity-20"
					style={{ backgroundColor: tabActiveForeground }}
				></div>
				<div
					className="h-2 w-2 rounded-sm"
					style={{ backgroundColor: badgeForeground }}
				></div>
			</div>
			<div
				className="pb-1.5 px-4 pt-3 flex flex-row items-center gap-2"
				style={{ backgroundColor: listInactiveSelectionBackground }}
			>
				<div
					className="h-1 rounded-xs w-14 opacity-20"
					style={{ backgroundColor: foreground }}
				></div>
				<div
					className="h-1 rounded-xs w-21 opacity-20"
					style={{ backgroundColor: foreground }}
				></div>
			</div>
			<div
				className="py-1.5 px-4 flex flex-row items-center gap-2"
				style={{ backgroundColor: listInactiveSelectionBackground }}
			>
				<div
					className="h-1 rounded-xs w-2/3 opacity-20"
					style={{ backgroundColor: foreground }}
				></div>
			</div>
			<div
				className="py-1.5 px-4 flex flex-row items-center gap-2"
				style={{ backgroundColor: listActiveSelectionBackground }}
			>
				<div
					className="h-1 rounded-xs w-full opacity-20"
					style={{ backgroundColor: foreground }}
				></div>
			</div>
			<div
				className={`font-mono text-[0.6rem] leading-[1rem] px-4 py-2 text-left ${parentClass} ${
					loading ? "text-transparent" : ""
				}`}
				style={{ backgroundColor: editorBackground }}
			>
				<style>{tokenCSS}</style>
				{codeHtml && (
					<div
						dangerouslySetInnerHTML={{
							__html: codeHtml,
						}}
					></div>
				)}
			</div>
			<div
				className="flex flex-row gap-2 px-4 pb-4 rounded-b-xl"
				style={{ backgroundColor: editorBackground }}
			>
				<div
					className="border-1 bg-gray rounded-sm grow"
					style={{ borderColor: editorGroupBorder }}
				></div>
				<div
					className="rounded-sm w-4 h-4"
					style={{
						backgroundColor: buttonBackground,
						backgroundImage: `linear-gradient(90deg, ${buttonGradient} 0, transparent 100%)`,
					}}
				></div>
			</div>
			{loading && (
				<div className="absolute h-full w-full top-0 left-0 flex items-center justify-center">
					<Spinner />
				</div>
			)}
		</div>
	);
}
