import Button from "@/components/Low/Button";
import ModuleTitle from "@/components/Medium/ModuleTitle";
import {moduleResultText} from "@/constants/ielts";
import {Module} from "@/interfaces";
import {User} from "@/interfaces/user";
import useExamStore from "@/stores/examStore";
import {calculateBandScore} from "@/utils/score";
import clsx from "clsx";
import Link from "next/link";
import {useRouter} from "next/router";
import {Fragment, useEffect, useState} from "react";
import {BsArrowCounterclockwise, BsBook, BsClipboard, BsEyeFill, BsHeadphones, BsMegaphone, BsPen, BsShareFill} from "react-icons/bs";
import {LevelScore} from "@/constants/ielts";
import {getLevelScore} from "@/utils/score";

interface Score {
	module: Module;
	correct: number;
	total: number;
	missing: number;
}

interface Props {
	user: User;
	modules: Module[];
	scores: Score[];
	isLoading: boolean;
	onViewResults: () => void;
}

export default function Finish({user, scores, modules, isLoading, onViewResults}: Props) {
	const [selectedModule, setSelectedModule] = useState(modules[0]);
	const [selectedScore, setSelectedScore] = useState<Score>(scores.find((x) => x.module === modules[0])!);

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

	useEffect(() => setSelectedScore(scores.find((x) => x.module === selectedModule)!), [scores, selectedModule]);

	const moduleColors: {[key in Module]: {progress: string; inner: string}} = {
		reading: {
			progress: "text-ielts-reading",
			inner: "bg-ielts-reading-light",
		},
		listening: {
			progress: "text-ielts-listening",
			inner: "bg-ielts-listening-light",
		},
		writing: {
			progress: "text-ielts-writing",
			inner: "bg-ielts-writing-light",
		},
		speaking: {
			progress: "text-ielts-speaking",
			inner: "bg-ielts-speaking-light",
		},
		level: {
			progress: "text-ielts-level",
			inner: "bg-ielts-level-light",
		},
	};

	const getTotalExercises = () => {
		const exam = exams.find((x) => x.module === selectedModule)!;
		if (exam.module === "reading" || exam.module === "listening") {
			return exam.parts.flatMap((x) => x.exercises).length;
		}

		return exam.exercises.length;
	};

	const bandScore: number = calculateBandScore(selectedScore.correct, selectedScore.total, selectedModule, user.focus);

	const showLevel = (level: number) => {
		if (selectedModule === "level") {
			const [levelStr, grade] = getLevelScore(level);
			return (
				<div className="flex flex-col items-center justify-center gap-1">
					<span className="text-xl font-bold">{levelStr}</span>
					<span className="text-xl">{grade}</span>
				</div>
			);
		}

		return <span className="text-3xl font-bold">{level}</span>;
	};

	return (
		<>
			<div className="w-full min-h-full h-fit flex flex-col items-center justify-between gap-8">
				<ModuleTitle
					module={selectedModule}
					totalExercises={getTotalExercises()}
					exerciseIndex={getTotalExercises()}
					minTimer={exams.find((x) => x.module === selectedModule)!.minTimer}
					disableTimer
				/>
				<div className="flex gap-4 self-start">
					{modules.includes("reading") && (
						<div
							onClick={() => setSelectedModule("reading")}
							className={clsx(
								"flex gap-2 items-center rounded-xl p-4 cursor-pointer hover:shadow-lg transition duration-300 ease-in-out hover:bg-ielts-reading hover:text-white",
								selectedModule === "reading" ? "bg-ielts-reading text-white" : "bg-mti-gray-smoke text-ielts-reading",
							)}>
							<BsBook className="w-6 h-6" />
							<span className="font-semibold">Reading</span>
						</div>
					)}
					{modules.includes("listening") && (
						<div
							onClick={() => setSelectedModule("listening")}
							className={clsx(
								"flex gap-2 items-center rounded-xl p-4 cursor-pointer hover:shadow-lg transition duration-300 ease-in-out hover:bg-ielts-listening hover:text-white",
								selectedModule === "listening" ? "bg-ielts-listening text-white" : "bg-mti-gray-smoke text-ielts-listening",
							)}>
							<BsHeadphones className="w-6 h-6" />
							<span className="font-semibold">Listening</span>
						</div>
					)}
					{modules.includes("writing") && (
						<div
							onClick={() => setSelectedModule("writing")}
							className={clsx(
								"flex gap-2 items-center rounded-xl p-4 cursor-pointer hover:shadow-lg transition duration-300 ease-in-out hover:bg-ielts-writing hover:text-white",
								selectedModule === "writing" ? "bg-ielts-writing text-white" : "bg-mti-gray-smoke text-ielts-writing",
							)}>
							<BsPen className="w-6 h-6" />
							<span className="font-semibold">Writing</span>
						</div>
					)}
					{modules.includes("speaking") && (
						<div
							onClick={() => setSelectedModule("speaking")}
							className={clsx(
								"flex gap-2 items-center rounded-xl p-4 cursor-pointer hover:shadow-lg transition duration-300 ease-in-out hover:bg-ielts-speaking hover:text-white",
								selectedModule === "speaking" ? "bg-ielts-speaking text-white" : "bg-mti-gray-smoke text-ielts-speaking",
							)}>
							<BsMegaphone className="w-6 h-6" />
							<span className="font-semibold">Speaking</span>
						</div>
					)}
					{modules.includes("level") && (
						<div
							onClick={() => setSelectedModule("level")}
							className={clsx(
								"flex gap-2 items-center rounded-xl p-4 cursor-pointer hover:shadow-lg transition duration-300 ease-in-out hover:bg-ielts-level hover:text-white",
								selectedModule === "level" ? "bg-ielts-level text-white" : "bg-mti-gray-smoke text-ielts-level",
							)}>
							<BsClipboard className="w-6 h-6" />
							<span className="font-semibold">Level</span>
						</div>
					)}
				</div>
				{isLoading && (
					<div className="w-fit h-fit absolute top-1/2 -translate-y-1/2 left-1/2 -translate-x-1/2 animate-pulse flex flex-col gap-12 items-center">
						<span className={clsx("loading loading-infinity w-32", moduleColors[selectedModule].progress)} />
						<span className={clsx("font-bold text-2xl text-center", moduleColors[selectedModule].progress)}>
							Evaluating your answers, please be patient...
							<br />
							You can also check it later on your records page!
						</span>
					</div>
				)}
				{!isLoading && (
					<div className="w-full flex gap-9 mt-32 items-center justify-between mb-20">
						<span className="max-w-3xl">{moduleResultText(selectedModule, bandScore)}</span>
						<div className="flex gap-9 px-16">
							<div
								className={clsx("radial-progress overflow-hidden", moduleColors[selectedModule].progress)}
								style={
									{"--value": (selectedScore.correct / selectedScore.total) * 100, "--thickness": "12px", "--size": "13rem"} as any
								}>
								<div
									className={clsx(
										"w-48 h-48 rounded-full flex flex-col items-center justify-center",
										moduleColors[selectedModule].inner,
									)}>
									<span className="text-xl">Level</span>
									{showLevel(bandScore)}
								</div>
							</div>
							<div className="flex flex-col gap-5">
								<div className="flex gap-2">
									<div className="w-3 h-3 bg-mti-red-light rounded-full mt-1" />
									<div className="flex flex-col">
										<span className="text-mti-red-light">
											{(((selectedScore.total - selectedScore.missing) / selectedScore.total) * 100).toFixed(0)}%
										</span>
										<span className="text-lg">Completion</span>
									</div>
								</div>
								<div className="flex gap-2">
									<div className="w-3 h-3 bg-mti-purple-light rounded-full mt-1" />
									<div className="flex flex-col">
										<span className="text-mti-purple-light">{selectedScore.correct.toString().padStart(2, "0")}</span>
										<span className="text-lg">Correct</span>
									</div>
								</div>
								<div className="flex gap-2">
									<div className="w-3 h-3 bg-mti-rose-light rounded-full mt-1" />
									<div className="flex flex-col">
										<span className="text-mti-rose-light">
											{(selectedScore.total - selectedScore.correct).toString().padStart(2, "0")}
										</span>
										<span className="text-lg">Wrong</span>
									</div>
								</div>
							</div>
						</div>
					</div>
				)}
			</div>

			{!isLoading && (
				<div className="self-end flex justify-between w-full gap-8 absolute bottom-8 left-0 px-8">
					<div className="flex gap-8">
						<div className="w-fit flex flex-col items-center gap-1 cursor-pointer">
							<button
								onClick={() => window.location.reload()}
								className="w-11 h-11 rounded-full bg-mti-purple-light hover:bg-mti-purple flex items-center justify-center transition duration-300 ease-in-out">
								<BsArrowCounterclockwise className="text-white w-7 h-7" />
							</button>
							<span>Play Again</span>
						</div>
						<div className="w-fit flex flex-col items-center gap-1 cursor-pointer">
							<button
								onClick={onViewResults}
								className="w-11 h-11 rounded-full bg-mti-purple-light hover:bg-mti-purple flex items-center justify-center transition duration-300 ease-in-out">
								<BsEyeFill className="text-white w-7 h-7" />
							</button>
							<span>Review Answers</span>
						</div>
					</div>

					<Link href="/" className="max-w-[200px] w-full self-end">
						<Button color="purple" className="max-w-[200px] self-end w-full">
							Dashboard
						</Button>
					</Link>
				</div>
			)}
		</>
	);
}
