import {errorButtonStyle, infoButtonStyle} from "@/constants/buttonStyles";
import {MatchSentenceExerciseOption, MatchSentenceExerciseSentence, MatchSentencesExercise} 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 LineTo from "react-lineto";
import {CommonProps} from ".";
import Button from "../Low/Button";
import Xarrow from "react-xarrows";
import useExamStore from "@/stores/examStore";
import {DndContext, DragEndEvent, useDraggable, useDroppable} from "@dnd-kit/core";

function DroppableQuestionArea({question, answer}: {question: MatchSentenceExerciseSentence; answer?: string}) {
	const {isOver, setNodeRef} = useDroppable({id: `droppable_sentence_${question.id}`});

	return (
		<div className="grid grid-cols-3 gap-4" ref={setNodeRef}>
			<div className="flex items-center gap-3 cursor-pointer col-span-2">
				<button
					className={clsx(
						"bg-mti-purple-ultralight text-mti-purple hover:text-white hover:bg-mti-purple w-8 h-8 rounded-full z-10",
						"transition duration-300 ease-in-out",
					)}>
					{question.id}
				</button>
				<span>{question.sentence}</span>
			</div>
			<div
				key={`answer_${question.id}_${answer}`}
				className={clsx("w-48 h-10 border rounded-xl flex items-center justify-center", isOver && "border-mti-purple-light")}>
				{answer && `Paragraph ${answer}`}
			</div>
		</div>
	);
}

function DraggableOptionArea({option}: {option: MatchSentenceExerciseOption}) {
	const {attributes, listeners, setNodeRef, transform} = useDraggable({
		id: `draggable_option_${option.id}`,
	});

	const style = transform
		? {
				transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
				zIndex: 99,
		  }
		: undefined;

	return (
		<div className={clsx("flex items-center justify-start gap-6 cursor-pointer")} ref={setNodeRef} style={style} {...listeners} {...attributes}>
			<button
				id={`option_${option.id}`}
				// onClick={() => selectOption(id)}
				className={clsx(
					"bg-mti-purple-ultralight text-mti-purple hover:text-white hover:bg-mti-purple px-3 py-2 rounded-full z-10",
					"transition duration-300 ease-in-out",
					option.id,
				)}>
				Paragraph {option.id}
			</button>
		</div>
	);
}

export default function MatchSentences({id, options, type, prompt, sentences, userSolutions, onNext, onBack}: MatchSentencesExercise & CommonProps) {
	const [answers, setAnswers] = useState<{question: string; option: string}[]>(userSolutions);

	const hasExamEnded = useExamStore((state) => state.hasExamEnded);

	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 = () => {
		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};
	};

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

	return (
		<>
			<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) => (
						<Fragment key={index}>
							{line}
							<br />
						</Fragment>
					))}
				</span>

				<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>

			<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>
		</>
	);
}
