import { MatchSentencesExercise } from "@/interfaces/exam";
import clsx from "clsx";
import { Fragment, useCallback, useEffect, useState } from "react";
import { CommonProps } from "../types";
import { DndContext, DragEndEvent } from "@dnd-kit/core";
import { DraggableOptionArea, DroppableQuestionArea } from "./DragNDrop";
import PracticeBadge from "../../Low/PracticeBadge";

const MatchSentences: React.FC<MatchSentencesExercise & CommonProps> = ({
	id,
	options,
	type,
	prompt,
	sentences,
	userSolutions,
	isPractice = false,
	registerSolution,
	headerButtons,
	footerButtons,
}) => {
	const [answers, setAnswers] = useState<{ question: string; option: string }[]>(userSolutions);

	const handleDragEnd = (event: DragEndEvent) => {
		if (event.over && event.over.id.toString().startsWith("droppable")) {
			const optionID = event.active.id.toString().replace("draggable_option_", "");
			const sentenceID = event.over.id.toString().replace("droppable_sentence_", "");

			setAnswers((prev) => [...prev.filter((x) => x.question.toString() !== sentenceID), { question: sentenceID, option: optionID }]);
		}
	};

	const calculateScore = useCallback(() => {
		const total = sentences.length;
		const correct = answers.filter(
			(x) => sentences.find((y) => y.id.toString() === x.question.toString())?.solution === x.option || false,
		).length;
		const missing = total - answers.filter((x) => sentences.find((y) => y.id.toString() === x.question.toString())).length;

		return { total, correct, missing };
	}, [answers, sentences]);

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

	return (
		<div className="flex flex-col gap-4 mt-4">
			{headerButtons}
			<div className={clsx("flex flex-col gap-4 mt-4", (headerButtons && footerButtons) && "mb-20")}>
				<span className="text-sm w-full leading-6">
					{prompt.split("\\n").map((line, index) => (
						<Fragment key={index}>
							{line}
							<br />
						</Fragment>
					))}
				</span>
				{isPractice && <PracticeBadge className="w-fit self-end" />}
				<DndContext onDragEnd={handleDragEnd}>
					<div className="flex flex-col gap-8 w-full items-center justify-between bg-mti-gray-smoke rounded-xl px-24 py-6">
						<div className="flex flex-col gap-4">
							{sentences.map((question) => (
								<DroppableQuestionArea
									key={`question_${question.id}`}
									question={question}
									answer={answers.find((x) => x.question.toString() === question.id.toString())?.option}
								/>
							))}
						</div>
						<div className="flex flex-col gap-4">
							<span>Drag one of these paragraphs into the slots above:</span>
							<div className="flex gap-4 flex-wrap justify-center items-center max-w-lg">
								{options.map((option) => (
									<DraggableOptionArea key={`answer_${option.id}`} option={option} />
								))}
							</div>
						</div>
					</div>
				</DndContext>
			</div>
			{footerButtons}
		</div>
	);
}

export default MatchSentences;
