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,
	isPractice = false,
	disableProgressButtons = false
}: MatchSentencesExercise & CommonProps) {
	const [answers, setAnswers] = useState<{ question: string; option: string }[]>(userSolutions);

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

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

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

	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 (disableProgressButtons) onNext({ exercise: id, solutions: answers, score: calculateScore(), type, isPractice });
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [answers, disableProgressButtons])

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

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

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

	return (
		<div className="flex flex-col gap-4 mt-4">
			{!disableProgressButtons && progressButtons()}

			<div className={clsx("flex flex-col gap-4 mt-4", !disableProgressButtons && "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>

			{!disableProgressButtons && progressButtons()}
		</div>
	);
}
