import {renderExercise} from "@/components/Exercises";
import ModuleTitle from "@/components/Medium/ModuleTitle";
import {renderSolution} from "@/components/Solutions";
import {infoButtonStyle} from "@/constants/buttonStyles";
import {UserSolution, SpeakingExam, SpeakingExercise, InteractiveSpeakingExercise} from "@/interfaces/exam";
import useExamStore from "@/stores/examStore";
import {defaultUserSolutions} from "@/utils/exams";
import {countExercises} from "@/utils/moduleUtils";
import {convertCamelCaseToReadable} from "@/utils/string";
import {mdiArrowRight} from "@mdi/js";
import Icon from "@mdi/react";
import clsx from "clsx";
import {Fragment, useEffect, useState} from "react";
import {toast} from "react-toastify";

interface Props {
	exam: SpeakingExam;
	showSolutions?: boolean;
	onFinish: (userSolutions: UserSolution[]) => void;
}

export default function Speaking({exam, showSolutions = false, onFinish}: Props) {
	const [speakingPromptsDone, setSpeakingPromptsDone] = useState<{id: string; amount: number}[]>([]);

	const {userSolutions, setUserSolutions} = useExamStore((state) => state);
	const {questionIndex, setQuestionIndex} = useExamStore((state) => state);
	const {hasExamEnded, setHasExamEnded} = useExamStore((state) => state);
	const {exerciseIndex, setExerciseIndex} = useExamStore((state) => state);

	const scrollToTop = () => Array.from(document.getElementsByTagName("body")).forEach((body) => body.scrollTo(0, 0));

	const nextExercise = (solution?: UserSolution) => {
		scrollToTop();
		if (solution) {
			setUserSolutions([...userSolutions.filter((x) => x.exercise !== solution.exercise), {...solution, module: "speaking", exam: exam.id}]);
		}

		if (questionIndex > 0) {
			const exercise = getExercise();
			setSpeakingPromptsDone((prev) => [...prev.filter((x) => x.id !== exercise.id), {id: exercise.id, amount: questionIndex}]);
		}
		setQuestionIndex(0);

		if (exerciseIndex + 1 < exam.exercises.length) {
			setExerciseIndex(exerciseIndex + 1);
			return;
		}

		if (exerciseIndex >= exam.exercises.length) return;

		setHasExamEnded(false);

		if (solution) {
			onFinish([...userSolutions.filter((x) => x.exercise !== solution.exercise), {...solution, module: "speaking", exam: exam.id}]);
		} else {
			onFinish(userSolutions);
		}
	};

	const previousExercise = (solution?: UserSolution) => {
		scrollToTop();
		if (solution) {
			setUserSolutions([...userSolutions.filter((x) => x.exercise !== solution.exercise), {...solution, module: "speaking", exam: exam.id}]);
		}

		if (exerciseIndex > 0) {
			setExerciseIndex(exerciseIndex - 1);
		}
	};

	const getExercise = () => {
		const exercise = exam.exercises[exerciseIndex];
		return {
			...exercise,
			variant: exerciseIndex < 2 && exercise.type === "interactiveSpeaking" ? "initial" : undefined,
			userSolutions: userSolutions.find((x) => x.exercise === exercise.id)?.solutions || [],
		} as SpeakingExercise | InteractiveSpeakingExercise;
	};

	return (
		<>
			<div className="flex flex-col h-full w-full gap-8 items-center">
				<ModuleTitle
					label={convertCamelCaseToReadable(exam.exercises[exerciseIndex].type)}
					minTimer={exam.minTimer}
					exerciseIndex={exerciseIndex + 1 + questionIndex + speakingPromptsDone.reduce((acc, curr) => acc + curr.amount, 0)}
					module="speaking"
					totalExercises={countExercises(exam.exercises)}
					disableTimer={showSolutions}
				/>
				{exerciseIndex > -1 &&
					exerciseIndex < exam.exercises.length &&
					!showSolutions &&
					renderExercise(getExercise(), exam.id, nextExercise, previousExercise)}
				{exerciseIndex > -1 &&
					exerciseIndex < exam.exercises.length &&
					showSolutions &&
					renderSolution(exam.exercises[exerciseIndex], nextExercise, previousExercise)}
			</div>
		</>
	);
}
