import {errorButtonStyle, infoButtonStyle} from "@/constants/buttonStyles";
import {FillBlanksExercise} from "@/interfaces/exam";
import {Dialog, Transition} from "@headlessui/react";
import clsx from "clsx";
import {Fragment, useState} from "react";
import reactStringReplace from "react-string-replace";

interface WordsPopoutProps {
	words: {word: string; isDisabled: boolean}[];
	isOpen: boolean;
	onCancel: () => void;
	onAnswer: (answer: string) => void;
}

function WordsPopout({words, isOpen, onCancel, onAnswer}: WordsPopoutProps) {
	return (
		<Transition appear show={isOpen} as={Fragment}>
			<Dialog as="div" className="relative z-10" onClose={onCancel}>
				<Transition.Child
					as={Fragment}
					enter="ease-out duration-300"
					enterFrom="opacity-0"
					enterTo="opacity-100"
					leave="ease-in duration-200"
					leaveFrom="opacity-100"
					leaveTo="opacity-0">
					<div className="fixed inset-0 bg-black bg-opacity-25" />
				</Transition.Child>

				<div className="fixed inset-0 overflow-y-auto">
					<div className="flex min-h-full items-center justify-center p-4 text-center">
						<Transition.Child
							as={Fragment}
							enter="ease-out duration-300"
							enterFrom="opacity-0 scale-95"
							enterTo="opacity-100 scale-100"
							leave="ease-in duration-200"
							leaveFrom="opacity-100 scale-100"
							leaveTo="opacity-0 scale-95">
							<Dialog.Panel className="w-fit transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all flex flex-col">
								<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-gray-900">
									List of words
								</Dialog.Title>
								<div className="mt-4 grid grid-cols-3 gap-4">
									{words.map((word) => (
										<button
											key={word.word}
											onClick={() => onAnswer(word.word)}
											disabled={word.isDisabled}
											className={clsx("btn btn-wide gap-4 relative text-white", infoButtonStyle)}>
											{word.word}
										</button>
									))}
								</div>

								<div className="mt-4 self-end">
									<button onClick={onCancel} className={clsx("btn btn-wide gap-4 relative text-white", errorButtonStyle)}>
										Close
									</button>
								</div>
							</Dialog.Panel>
						</Transition.Child>
					</div>
				</div>
			</Dialog>
		</Transition>
	);
}

export default function FillBlanks({allowRepetition, prompt, solutions, text, words}: FillBlanksExercise) {
	const [userSolutions, setUserSolutions] = useState<{id: string; solution: string}[]>([]);
	const [currentBlankId, setCurrentBlankId] = useState<string>();

	const renderLines = (line: string) => {
		return (
			<span>
				{reactStringReplace(line, /({{\d}})/g, (match) => {
					const id = match.replaceAll(/[\{\}]/g, "");
					const userSolution = userSolutions.find((x) => x.id === id);

					return (
						<button className="border-2 rounded-xl px-4 text-blue-400 border-blue-400" onClick={() => setCurrentBlankId(id)}>
							{userSolution ? userSolution.solution : id}
						</button>
					);
				})}
			</span>
		);
	};

	return (
		<div className="flex flex-col">
			<WordsPopout
				words={words.map((word) => ({word, isDisabled: allowRepetition ? false : userSolutions.map((x) => x.solution).includes(word)}))}
				isOpen={!!currentBlankId}
				onCancel={() => setCurrentBlankId(undefined)}
				onAnswer={(solution: string) => {
					setUserSolutions((prev) => [...prev.filter((x) => x.id !== currentBlankId), {id: currentBlankId!, solution}]);
					setCurrentBlankId(undefined);
				}}
			/>
			<span className="text-lg font-medium text-center px-48">{prompt}</span>
			<span>
				{text.split("\n").map((line) => (
					<>
						{renderLines(line)}
						<br />
					</>
				))}
			</span>
		</div>
	);
}
