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, getGradingLabel} 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,
	BsBan,
	BsBook,
	BsClipboard,
	BsClipboardFill,
	BsEyeFill,
	BsHeadphones,
	BsMegaphone,
	BsPen,
	BsShareFill,
} from "react-icons/bs";
import {LevelScore} from "@/constants/ielts";
import {getLevelScore} from "@/utils/score";
import {capitalize} from "lodash";
import Modal from "@/components/Modal";
import {UserSolution} from "@/interfaces/exam";
import ai_usage from "@/utils/ai.detection";
import useGradingSystem from "@/hooks/useGrading";
import {Assignment} from "@/interfaces/results";

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

interface Props {
	user: User;
	modules: Module[];
	scores: Score[];
	information: {
		timeSpent?: number;
		inactivity?: number;
	};
	solutions: UserSolution[];
	isLoading: boolean;
	assignment?: Assignment;
	onViewResults: (moduleIndex?: number) => void;
}

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

	const aiUsage = Math.round(ai_usage(solutions) * 100);
	const exams = useExamStore((state) => state.exams);
	const {gradingSystem} = useGradingSystem();

	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" || exam.module === "level") {
			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 label = getGradingLabel(level, gradingSystem?.steps || []);
			return (
				<div className="flex flex-col items-center justify-center gap-1">
					<span className="text-xl font-bold">{label}</span>
				</div>
			);
		}

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

	return (
		<>
			<Modal title="Extra Information" isOpen={isExtraInformationOpen} onClose={() => setIsExtraInformationOpen(false)}>
				<div className="flex flex-col gap-2 mt-4">
					{!!information.timeSpent && (
						<span>
							<b>Time Spent:</b> {Math.floor(information.timeSpent / 60)} minute(s)
						</span>
					)}
					{!!information.inactivity && (
						<span>
							<b>Inactivity:</b> {Math.floor(information.inactivity / 60)} minute(s)
						</span>
					)}
				</div>
			</Modal>

			<div className="flex h-fit min-h-full w-full 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 w-full">
					{modules.includes("reading") && (
						<div
							onClick={() => setSelectedModule("reading")}
							className={clsx(
								"hover:bg-ielts-reading flex cursor-pointer items-center gap-2 rounded-xl p-4 transition duration-300 ease-in-out hover:text-white hover:shadow-lg",
								selectedModule === "reading" ? "bg-ielts-reading text-white" : "bg-mti-gray-smoke text-ielts-reading",
							)}>
							<BsBook className="h-6 w-6" />
							<span className="font-semibold">Reading</span>
						</div>
					)}
					{modules.includes("listening") && (
						<div
							onClick={() => setSelectedModule("listening")}
							className={clsx(
								"hover:bg-ielts-listening flex cursor-pointer items-center gap-2 rounded-xl p-4 transition duration-300 ease-in-out hover:text-white hover:shadow-lg",
								selectedModule === "listening" ? "bg-ielts-listening text-white" : "bg-mti-gray-smoke text-ielts-listening",
							)}>
							<BsHeadphones className="h-6 w-6" />
							<span className="font-semibold">Listening</span>
						</div>
					)}
					{modules.includes("writing") && (
						<div className="flex w-full justify-between items-center">
							<div
								onClick={() => setSelectedModule("writing")}
								className={clsx(
									"hover:bg-ielts-writing flex cursor-pointer items-center gap-2 rounded-xl p-4 transition duration-300 ease-in-out hover:text-white hover:shadow-lg",
									selectedModule === "writing" ? "bg-ielts-writing text-white" : "bg-mti-gray-smoke text-ielts-writing",
								)}>
								<BsPen className="h-6 w-6" />
								<span className="font-semibold">Writing</span>
							</div>
							{aiUsage >= 50 && user.type !== "student" && (
								<div
									className={clsx("flex items-center justify-center border px-3 h-full rounded", {
										"bg-orange-100 border-orange-400 text-orange-700": aiUsage < 80,
										"bg-red-100 border-red-400 text-red-700": aiUsage >= 80,
									})}>
									<span className="text-xs">AI Usage</span>
								</div>
							)}
						</div>
					)}
					{modules.includes("speaking") && (
						<div
							onClick={() => setSelectedModule("speaking")}
							className={clsx(
								"hover:bg-ielts-speaking flex cursor-pointer items-center gap-2 rounded-xl p-4 transition duration-300 ease-in-out hover:text-white hover:shadow-lg",
								selectedModule === "speaking" ? "bg-ielts-speaking text-white" : "bg-mti-gray-smoke text-ielts-speaking",
							)}>
							<BsMegaphone className="h-6 w-6" />
							<span className="font-semibold">Speaking</span>
						</div>
					)}
					{modules.includes("level") && (
						<div
							onClick={() => setSelectedModule("level")}
							className={clsx(
								"hover:bg-ielts-level flex cursor-pointer items-center gap-2 rounded-xl p-4 transition duration-300 ease-in-out hover:text-white hover:shadow-lg",
								selectedModule === "level" ? "bg-ielts-level text-white" : "bg-mti-gray-smoke text-ielts-level",
							)}>
							<BsClipboard className="h-6 w-6" />
							<span className="font-semibold">Level</span>
						</div>
					)}
				</div>
				{isLoading && (
					<div className="absolute left-1/2 top-1/2 flex h-fit w-fit -translate-x-1/2 -translate-y-1/2 animate-pulse flex-col items-center gap-12">
						<span className={clsx("loading loading-infinity w-32", moduleColors[selectedModule].progress)} />
						<span className={clsx("text-center text-2xl font-bold", moduleColors[selectedModule].progress)}>
							Evaluating your answers, please be patient...
							<br />
							You can also check it later on your records page!
						</span>
					</div>
				)}
				{assignment && !assignment.released && !isLoading && (
					<div className="absolute left-1/2 top-1/2 flex h-fit w-fit -translate-x-1/2 -translate-y-1/2 flex-col items-center gap-12">
						{/* <span className={clsx("loading loading-infinity w-32", moduleColors[selectedModule].progress)} /> */}
						<BsBan size={64} className={clsx(moduleColors[selectedModule].progress)} />
						<span className={clsx("text-center text-2xl font-bold", moduleColors[selectedModule].progress)}>
							This exam has not yet been released by its assigner.
							<br />
							You can check it later on your records page when it is released!
						</span>
					</div>
				)}
				{!isLoading && !(assignment && !assignment.released) && (
					<div className="mb-20 mt-32 flex w-full items-center justify-between gap-9">
						<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(
										"flex h-48 w-48 flex-col items-center justify-center rounded-full",
										moduleColors[selectedModule].inner,
									)}>
									<span className="text-xl">Level</span>
									{showLevel(bandScore)}
								</div>
							</div>
							{!["writing", "speaking"].includes(selectedModule) ? (
								<div className="flex flex-col gap-5 w-28">
									<div className="flex gap-2">
										<div className="bg-mti-red-light mt-1 h-3 w-3 rounded-full" />
										<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="bg-mti-purple-light mt-1 h-3 w-3 rounded-full" />
										<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="bg-mti-rose-light mt-1 h-3 w-3 rounded-full" />
										<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 className="w-28 h-full" />
							)}
						</div>
					</div>
				)}
			</div>

			{!isLoading && (
				<div className="absolute bottom-8 left-0 flex w-full justify-between gap-8 self-end px-8">
					<div className="flex gap-8">
						<div className="flex w-fit cursor-pointer flex-col items-center gap-1">
							<button
								onClick={() => window.location.reload()}
								// disabled={user.type === "admin"}
								// TODO: temporarily disabled
								disabled
								className="bg-mti-purple-light hover:bg-mti-purple flex h-11 w-11 items-center justify-center rounded-full transition duration-300 ease-in-out">
								<BsArrowCounterclockwise className="h-7 w-7 text-white" />
							</button>
							<span>Play Again</span>
						</div>
						<div className="flex w-fit cursor-pointer flex-col items-center gap-1">
							<button
								onClick={() => onViewResults()}
								disabled={assignment && !assignment.released}
								className="bg-mti-purple-light hover:bg-mti-purple flex h-11 w-11 items-center justify-center rounded-full transition duration-300 ease-in-out">
								<BsEyeFill className="h-7 w-7 text-white" />
							</button>
							<span>Review All</span>
						</div>
						<div className="flex w-fit cursor-pointer flex-col items-center gap-1">
							<button
								disabled={assignment && !assignment.released}
								onClick={() => onViewResults(modules.findIndex((x) => x === selectedModule))}
								className="bg-mti-purple-light hover:bg-mti-purple flex h-11 w-11 items-center justify-center rounded-full transition duration-300 ease-in-out">
								<BsEyeFill className="h-7 w-7 text-white" />
							</button>
							<span>Review {capitalize(selectedModule)}</span>
						</div>
						{(!!information.inactivity || !!information.timeSpent) && (
							<div className="flex w-fit cursor-pointer flex-col items-center gap-1">
								<button
									onClick={() => setIsExtraInformationOpen(true)}
									className="bg-mti-purple-light hover:bg-mti-purple flex h-11 w-11 items-center justify-center rounded-full transition duration-300 ease-in-out">
									<BsClipboardFill className="h-7 w-7 text-white" />
								</button>
								<span>Extra Information</span>
							</div>
						)}
					</div>

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