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 {Fragment, useEffect, useState} from "react";
import reactStringReplace from "react-string-replace";
import {CommonProps} from ".";
import {toast} from "react-toastify";
import Button from "../Low/Button";
import useExamStore from "@/stores/examStore";

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

	useEffect(() => {
		const words = userInput.split(" ");
		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="py-2 px-3 mx-2 rounded-2xl w-48 bg-white focus:outline-none my-2"
			placeholder={id}
			onChange={(e) => setUserInput(e.target.value)}
			onBlur={() => setUserSolution(userInput)}
			value={userInput}
			contentEditable={showSolutions}
		/>
	);
}

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

	const {hasExamEnded, setCurrentSolution} = useExamStore((state) => state);

	useEffect(() => {
		if (hasExamEnded) onNext({exercise: id, solutions: answers, score: calculateScore(), type});
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [hasExamEnded]);

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

		return {total, correct, missing};
	};

	useEffect(() => {
		setCurrentSolution({exercise: id, solutions: answers, score: calculateScore(), type});
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [answers, setAnswers]);

	const renderLines = (line: string) => {
		return (
			<span className="text-base leading-5">
				{reactStringReplace(line, /({{\d+}})/g, (match) => {
					const id = match.replaceAll(/[\{\}]/g, "");
					const userSolution = answers.find((x) => x.id === id);
					const setUserSolution = (solution: string) => {
						setAnswers((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 gap-4">
			<div className="flex justify-between w-full gap-8">
				<Button
					color="purple"
					variant="outline"
					onClick={() => onBack({exercise: id, solutions: answers, score: calculateScore(), type})}
					className="max-w-[200px] w-full">
					Back
				</Button>

				<Button
					color="purple"
					onClick={() => onNext({exercise: id, solutions: answers, score: calculateScore(), type})}
					className="max-w-[200px] self-end w-full">
					Next
				</Button>
			</div>

			<div className="flex flex-col gap-4 mt-4 h-full w-full mb-20">
				<span className="text-sm w-full leading-6">
					{prompt.split("\\n").map((line, index) => (
						<span key={index}>
							{line}
							<br />
						</span>
					))}
				</span>
				<span className="bg-mti-gray-smoke rounded-xl px-5 py-6">
					{text.split("\\n").map((line, index) => (
						<p key={index}>
							{renderLines(line)}
							<br />
						</p>
					))}
				</span>
			</div>

			<div className="self-end flex justify-between w-full gap-8 absolute bottom-8 left-0 px-8">
				<Button
					color="purple"
					variant="outline"
					onClick={() => onBack({exercise: id, solutions: answers, score: calculateScore(), type})}
					className="max-w-[200px] w-full">
					Back
				</Button>

				<Button
					color="purple"
					onClick={() => onNext({exercise: id, solutions: answers, score: calculateScore(), type})}
					className="max-w-[200px] self-end w-full">
					Next
				</Button>
			</div>
		</div>
	);
}
