import { Exercise, ReadingExam, UserSolution } from "@/interfaces/exam";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import clsx from "clsx";
import { convertCamelCaseToReadable } from "@/utils/string";
import { renderExercise } from "@/components/Exercises";
import { renderSolution } from "@/components/Solutions";
import ModuleTitle from "@/components/Medium/ModuleTitle";
import BlankQuestionsModal from "@/components/QuestionsModal";
import { countExercises } from "@/utils/moduleUtils";
import PartDivider from "./Navigation/SectionDivider";
import ReadingPassage from "./components/ReadingPassage";
//import ReadingPassageModal from "./components/ReadingPassageModal";
import { calculateExerciseIndex } from "./utils/calculateExerciseIndex";
import useExamNavigation from "./Navigation/useExamNavigation";
import { ExamProps } from "./types";
import useExamStore, { usePersistentExamStore } from "@/stores/exam";
import useExamTimer from "@/hooks/useExamTimer";
import SectionNavbar from "./Navigation/SectionNavbar";
import ProgressButtons from "./components/ProgressButtons";
import PracticeModal from "@/components/PracticeModal";

const Reading: React.FC<ExamProps<ReadingExam>> = ({ exam, showSolutions = false, preview = false }) => {
	const updateTimers = useExamTimer(exam.module, preview || showSolutions);
	const userSolutionRef = useRef<(() => UserSolution) | null>(null);
	const [solutionWasUpdated, setSolutionWasUpdated] = useState(false);

	const [showBlankModal, setShowBlankModal] = useState(false);
	//const [showTextModal, setShowTextModal] = useState(false);
	const [isTextMinimized, setIsTextMinimzed] = useState(false);

	const examState = useExamStore((state) => state);
	const persistentExamState = usePersistentExamStore((state) => state);

	const {
		exerciseIndex, partIndex, questionIndex,
		userSolutions, flags, timeSpentCurrentModule,
		setBgColor, setUserSolutions, setTimeIsUp,
		dispatch,
	} = !preview ? examState : persistentExamState;


	const timer = useRef(exam.minTimer - timeSpentCurrentModule / 60);

	const { finalizeModule, timeIsUp } = flags;

	const {
		nextExercise, previousExercise,
		showPartDivider, setShowPartDivider,
		seenParts, setSeenParts,
		isBetweenParts, setIsBetweenParts,
		startNow
	} = useExamNavigation({ exam, module: "reading", showBlankModal, setShowBlankModal, showSolutions, preview, disableBetweenParts: showSolutions });

	const hasPractice = useMemo(() => {
		if (partIndex > -1 && partIndex < exam.parts.length) {
			return exam.parts[partIndex].exercises.some(e => e.isPractice)
		}
		return false
	}, [partIndex, exam.parts])

	useEffect(() => {
		if (finalizeModule || timeIsUp) {
			updateTimers();

			if (timeIsUp) {
				setTimeIsUp(false);
			}
			dispatch({ type: "FINALIZE_MODULE", payload: { updateTimers: false } })
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [finalizeModule, timeIsUp])

	useEffect(() => {
		const listener = (e: KeyboardEvent) => {
			if (e.key === "F3" || ((e.ctrlKey || e.metaKey) && e.key === "f")) {
				e.preventDefault();
			}
		};
		document.addEventListener("keydown", listener);
		return () => {
			document.removeEventListener("keydown", listener);
		};
	}, []);

	const registerSolution = useCallback((updateSolution: () => UserSolution) => {
		userSolutionRef.current = updateSolution;
		setSolutionWasUpdated(true);
	}, []);

	useEffect(() => {
		if (solutionWasUpdated && userSolutionRef.current) {
			const solution = userSolutionRef.current();
			setUserSolutions([...userSolutions.filter((x) => x.exercise !== solution.exercise), { ...solution, module: "reading", exam: exam.id }]);
			setSolutionWasUpdated(false);
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [solutionWasUpdated])

	const currentExercise = useMemo<Exercise>(() => {
		const exercise = exam.parts[partIndex].exercises[exerciseIndex];
		return {
			...exercise,
			userSolutions: userSolutions.find((x) => x.exercise === exercise.id)?.solutions || [],
		};
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [partIndex, exerciseIndex]);


	const confirmFinishModule = (keepGoing?: boolean) => {
		if (!keepGoing) {
			setShowBlankModal(false);
			return;
		} else {
			nextExercise(true);
			setShowBlankModal(false);
		}
	};

	const memoizedExerciseIndex = useMemo(() =>
		calculateExerciseIndex(exam, partIndex, exerciseIndex, questionIndex)
		// eslint-disable-next-line react-hooks/exhaustive-deps
		, [partIndex, exerciseIndex, questionIndex]
	);

	const handlePartDividerClick = () => {
		setShowPartDivider(false);
		setBgColor("bg-white");
		setSeenParts((prev) => new Set(prev).add(partIndex));
	}

	useEffect(() => {
		if (partIndex !== 0 && !showSolutions) {
			setIsBetweenParts(true);
		}
	}, [partIndex, setIsBetweenParts, showSolutions])


	const progressButtons = useMemo(() =>
		// Do not remove the ()=> in handle next
		<ProgressButtons handlePrevious={previousExercise} handleNext={() => nextExercise()} />
		, [nextExercise, previousExercise]);

	return (
		<>
			{showPartDivider ?
				<div className="flex justify-center items-center h-full">
					<PartDivider
						module="reading"
						sectionLabel="Part"
						defaultTitle="Reading exam"
						section={exam.parts[partIndex]}
						sectionIndex={partIndex}
						onNext={() => handlePartDividerClick()}
					/>
				</div> : (
					<>
						<PracticeModal key={partIndex} open={hasPractice} />
						<div className="flex flex-col h-full w-full gap-8">
							<BlankQuestionsModal isOpen={showBlankModal} onClose={confirmFinishModule} />
							{/*<ReadingPassageModal text={exam.parts[partIndex].text} isOpen={showTextModal} onClose={() => setShowTextModal(false)} />*/}
							{exam.parts.length > 1 && <SectionNavbar
								module="reading"
								sectionLabel="Part"
								seenParts={seenParts}
								setShowPartDivider={setShowPartDivider}
								setSeenParts={setSeenParts}
								setIsBetweenParts={setIsBetweenParts}
								preview={preview}
							/>}
							<ModuleTitle
								minTimer={timer.current}
								exerciseIndex={memoizedExerciseIndex}
								module="reading"
								totalExercises={countExercises(exam.parts.flatMap((x) => x.exercises))}
								disableTimer={showSolutions || preview}
								label={convertCamelCaseToReadable(exam.parts[partIndex].exercises[exerciseIndex].type)}
								preview={preview}
							/>
							<div
								className={clsx(
									"mb-20 w-full",
									((startNow || isBetweenParts) && !showSolutions) ? "flex flex-col gap-2" : "grid grid-cols-2 gap-4",
								)}>
								<ReadingPassage
									exam={exam}
									partIndex={partIndex}
									exerciseType={currentExercise.type}
									isTextMinimized={isTextMinimized}
									setIsTextMinimized={setIsTextMinimzed}
								/>
								{!startNow && !showPartDivider && !showSolutions && !isBetweenParts && renderExercise(currentExercise, exam.id, registerSolution, preview, progressButtons, progressButtons)}
								{showSolutions && renderSolution(currentExercise, progressButtons, progressButtons)}
							</div>
							{/*exerciseIndex > -1 && partIndex > -1 && exerciseIndex < exam.parts[partIndex].exercises.length && (
								<Button
									color="purple"
									variant="outline"
									onClick={() => setShowTextModal(true)}
									className="max-w-[200px] self-end w-full absolute bottom-[31px] right-64">
									Read text
								</Button>
							)*/}
						</div>
						{((startNow || isBetweenParts) && !showPartDivider && !showSolutions) &&
							<ProgressButtons
								hidePrevious={partIndex == 0 && isBetweenParts || startNow}
								nextLabel={startNow ? "Start now" : "Next Page"}
								handlePrevious={previousExercise}
								handleNext={() => nextExercise()} />
						}
					</>
				)}
		</>
	);
}

export default Reading;
