import {errorButtonStyle, infoButtonStyle} from "@/constants/buttonStyles";
import {WriteBlanksExercise} from "@/interfaces/exam";
import {mdiArrowLeft, mdiArrowRight} from "@mdi/js";
import Icon from "@mdi/react";
import clsx from "clsx";
import {useEffect, useState} from "react";
import reactStringReplace from "react-string-replace";
import {CommonProps} from ".";
import {toast} from "react-toastify";

function Blank({
	id,
	maxWords,
	showSolutions = false,
	setUserSolution,
}: {
	id: string;
	solutions?: string[];
	userSolution?: string;
	maxWords: number;
	showSolutions?: boolean;
	setUserSolution?: (solution: string) => void;
}) {
	const [userInput, setUserInput] = useState("");

	useEffect(() => {
		const words = userInput.split(" ").filter((x) => x !== "");
		if (words.length >= maxWords) {
			toast.warning(`You have reached your word limit of ${maxWords} words!`, {toastId: "word-limit"});
			setUserInput(words.join(" ").trim());
		}
	}, [maxWords, userInput]);

	return (
		<input
			className={clsx("input border rounded-xl px-2 py-1 bg-white text-blue-400 border-blue-400 my-2")}
			placeholder={id}
			onChange={(e) => setUserInput(e.target.value)}
			value={userInput}
			contentEditable={showSolutions}
		/>
	);
}

export default function WriteBlanks({id, prompt, maxWords, solutions, text, onNext, onBack}: WriteBlanksExercise & CommonProps) {
	const [userSolutions, setUserSolutions] = useState<{id: string; solution: string}[]>([]);

	const calculateScore = () => {
		const total = text.match(/({{\d+}})/g)?.length || 0;
		const correct = userSolutions.filter(
			(x) =>
				solutions
					.find((y) => x.id === y.id)
					?.solution.map((y) => y.toLowerCase())
					.includes(x.solution.toLowerCase()) || false,
		).length;

		return {total, correct};
	};

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

					return <Blank userSolution={userSolution?.solution} maxWords={maxWords} id={id} setUserSolution={setUserSolution} />;
				})}
			</span>
		);
	};

	return (
		<>
			<div className="flex flex-col">
				<span className="text-lg font-medium text-center px-48">{prompt}</span>
				<span>
					{text.split("\n").map((line) => (
						<>
							{renderLines(line)}
							<br />
						</>
					))}
				</span>
			</div>

			<div className="self-end flex gap-8">
				<button className={clsx("btn btn-wide gap-4 relative text-white", errorButtonStyle)} onClick={onBack}>
					<div className="absolute left-4">
						<Icon path={mdiArrowLeft} color="white" size={1} />
					</div>
					Back
				</button>
				<button
					className={clsx("btn btn-wide gap-4 relative text-white", infoButtonStyle)}
					onClick={() => onNext({id, solutions: userSolutions, score: calculateScore()})}>
					Next
					<div className="absolute right-4">
						<Icon path={mdiArrowRight} color="white" size={1} />
					</div>
				</button>
			</div>
		</>
	);
}
