import { Module } from "@/interfaces";
import { moduleLabels } from "@/utils/moduleUtils";
import clsx from "clsx";
import { ReactNode, useState } from "react";
import { BsBook, BsClipboard, BsHeadphones, BsMegaphone, BsPen, BsStopwatch } from "react-icons/bs";
import ProgressBar from "../Low/ProgressBar";
import Timer from "./Timer";
import { Exercise, LevelExam, MultipleChoiceExercise, ShuffleMap, UserSolution } from "@/interfaces/exam";
import { BsFillGrid3X3GapFill } from "react-icons/bs";
import Button from "../Low/Button";
import useExamStore from "@/stores/examStore";
import Modal from "../Modal";
import React from "react";

interface Props {
	minTimer: number;
	module: Module;
	examLabel?: string;
	label?: string;
	exerciseIndex: number;
	totalExercises: number;
	disableTimer?: boolean;
	partLabel?: string;
	showTimer?: boolean;
	showSolutions?: boolean;
	currentExercise?: Exercise;
	runOnClick?: ((questionIndex: number) => void) | undefined;
}

export default function ModuleTitle({
	minTimer,
	module,
	label,
	examLabel,
	exerciseIndex,
	totalExercises,
	disableTimer = false,
	partLabel,
	showTimer = true,
	showSolutions = false,
	runOnClick = undefined
}: Props) {
	const {
		userSolutions,
		partIndex,
		exam
	} = useExamStore((state) => state);
	const examExerciseIndex = useExamStore((state) => state.exerciseIndex)

	const [isOpen, setIsOpen] = useState(false);

	const moduleIcon: { [key in Module]: ReactNode } = {
		reading: <BsBook className="text-ielts-reading w-6 h-6" />,
		listening: <BsHeadphones className="text-ielts-listening w-6 h-6" />,
		writing: <BsPen className="text-ielts-writing w-6 h-6" />,
		speaking: <BsMegaphone className="text-ielts-speaking w-6 h-6" />,
		level: <BsClipboard className="text-ielts-level w-6 h-6" />,
	};

	const isMultipleChoiceLevelExercise = () => {
		if (exam?.module === 'level' && typeof partIndex === "number" && partIndex > -1) {
			const currentExercise = (exam as LevelExam).parts[partIndex].exercises[examExerciseIndex];
			return currentExercise && currentExercise.type === 'multipleChoice';
		}
		return false;
	};

	const renderMCQuestionGrid = () => {
		if (!isMultipleChoiceLevelExercise() && !userSolutions) return null;

		const currentExercise = (exam as LevelExam).parts[partIndex!].exercises[examExerciseIndex] as MultipleChoiceExercise;
		const userSolution = userSolutions!.find((x) => x.exercise.toString() == currentExercise.id.toString())!;
		const answeredQuestions = new Set(userSolution.solutions.map(sol => sol.question.toString()));
		const exerciseOffset = Number(currentExercise.questions[0].id);
		const lastExercise = exerciseOffset + (currentExercise.questions.length - 1);

		const getQuestionColor = (questionId: string, solution: string, userQuestionSolution: string | undefined) => {
			const questionShuffleMap = userSolutions.reduce((foundMap, userSolution) => {
				if (foundMap) return foundMap;
				return userSolution.shuffleMaps?.find(map => map.questionID.toString() === questionId.toString()) || null;
			}, null as ShuffleMap | null);
			const newSolution = questionShuffleMap ? questionShuffleMap?.map[solution] : solution;

			if (!userSolutions) return "";

			if (!userQuestionSolution) {
				return "!bg-mti-gray-davy !border--mti-gray-davy !text-mti-gray-davy !text-white hover:!bg-gray-700";
			}

			return userQuestionSolution === newSolution ?
				"!bg-mti-purple-light !text-mti-purple-light !text-white hover:!bg-mti-purple-dark" :
				"!bg-mti-rose-light !border-mti-rose-light !text-mti-rose-light !text-white hover:!bg-mti-rose-dark";
		}
		return (
			<>
				<h3 className="text-xl font-semibold mb-4 text-center">{`Part ${partIndex + 1} (Questions ${exerciseOffset} - ${lastExercise})`}</h3>
				<div className="grid grid-cols-5 gap-3 px-4 py-2">
					{currentExercise.questions.map((_, index) => {
						const questionNumber = exerciseOffset + index;
						const isAnswered = answeredQuestions.has(questionNumber.toString());
						const solution = currentExercise.questions.find((x) => x.id.toString() == questionNumber.toString())!.solution;

						const userQuestionSolution = currentExercise.userSolutions?.find((x) => x.question.toString() == questionNumber.toString())?.option;
						return (
							<Button
								variant={showSolutions ? "solid" : (isAnswered ? "solid" : "outline")}
								key={index}
								className={clsx(
									"w-12 h-12 flex items-center justify-center rounded-lg text-sm font-bold transition-all duration-200 ease-in-out",
									(showSolutions ?
										getQuestionColor(questionNumber.toString(), solution, userQuestionSolution) :
										(isAnswered ?
											"bg-mti-purple-light border-mti-purple-light text-white hover:bg-mti-purple-dark hover:border-mti-purple-dark" :
											"bg-white border-gray-400 hover:bg-gray-100 hover:text-gray-700"
										)
									)
								)}
								onClick={() => { if (typeof runOnClick !== "undefined") { runOnClick(index); } setIsOpen(false); }}
							>
								{questionNumber}
							</Button>
						);
					})}
				</div>
				<p className="mt-4 text-sm text-gray-600 text-center">
					Click a question number to jump to that question
				</p>
			</>
		);
	};
	return (
		<>
			{showTimer && <Timer minTimer={minTimer} disableTimer={disableTimer} />}
			<div className="w-full">
				{partLabel && (
					<div className="text-3xl space-y-4">
						{partLabel.split("\n\n").map((partInstructions, index) => {
							if (index === 0)
								return (
									<p key={index} className="font-bold">
										{partInstructions}
									</p>
								);
							else
								return (
									<div key={index} className="text-2xl font-semibold flex flex-col gap-2">
										{partInstructions.split("\\n").map((line, lineIndex) => (
											<span key={lineIndex} dangerouslySetInnerHTML={{__html: line.replace('that is not correct', 'that is <span class="font-bold"><u>not correct</u></span>')}}></span>
										))}
									</div>
								);
						})}
					</div>
				)}
				<div className={clsx("flex gap-6 w-full h-fit items-center", partLabel ? "mt-10" : "mt-5")}>
					<div className="w-12 h-12 bg-mti-gray-smoke flex items-center justify-center rounded-lg">{moduleIcon[module]}</div>
					<div className="flex flex-col gap-3 w-full">
						<div className="w-full flex justify-between">
							<span className="text-base font-semibold">
								{module === "level"
									? (examLabel ? examLabel : "Placement Test")
									: `${moduleLabels[module]} exam${label ? ` - ${label}` : ''}`
								}
							</span>
							<span className="text-sm font-semibold self-end">
								Question {exerciseIndex}/{totalExercises}
							</span>
						</div>
						<ProgressBar color={module} label="" percentage={(exerciseIndex * 100) / totalExercises} className="h-2 w-full" />
					</div>
					{isMultipleChoiceLevelExercise() && (
						<>
							<Button variant="outline" onClick={() => setIsOpen(true)} padding="p-2" className="rounded-lg">
								<BsFillGrid3X3GapFill size={24} />
							</Button>
							<Modal
								isOpen={isOpen}
								onClose={() => setIsOpen(false)}
								className="w-full max-w-md transform overflow-hidden rounded-2xl bg-white shadow-xl transition-all"
							>
								<>
									{renderMCQuestionGrid()}
								</>
							</Modal>
						</>
					)}
				</div>
			</div>
		</>
	);
}