import Button from "@/components/Low/Button";
import ProgressBar from "@/components/Low/ProgressBar";
import InviteCard from "@/components/Medium/InviteCard";
import ProfileSummary from "@/components/ProfileSummary";
import useAssignments from "@/hooks/useAssignments";
import useGradingSystem from "@/hooks/useGrading";
import useInvites from "@/hooks/useInvites";
import useFilterRecordsByUser from "@/hooks/useFilterRecordsByUser";
import useUsers from "@/hooks/useUsers";
import {Invite} from "@/interfaces/invite";
import {Assignment} from "@/interfaces/results";
import {CorporateUser, MasterCorporateUser, Stat, User} from "@/interfaces/user";
import useExamStore from "@/stores/examStore";
import {getExamById} from "@/utils/exams";
import {getUserCorporate} from "@/utils/groups";
import {countExamModules, countFullExams, MODULE_ARRAY, sortByModule, sortByModuleName} from "@/utils/moduleUtils";
import {getGradingLabel, getLevelLabel, getLevelScore} from "@/utils/score";
import {averageScore, groupBySession} from "@/utils/stats";
import {CreateOrderActions, CreateOrderData, OnApproveActions, OnApproveData, OrderResponseBody} from "@paypal/paypal-js";
import {PayPalButtons} from "@paypal/react-paypal-js";
import axios from "axios";
import clsx from "clsx";
import {capitalize} from "lodash";
import moment from "moment";
import Link from "next/link";
import {useRouter} from "next/router";
import {useEffect, useState} from "react";
import {BsArrowRepeat, BsBook, BsClipboard, BsFileEarmarkText, BsHeadphones, BsMegaphone, BsPen, BsPencil, BsStar} from "react-icons/bs";
import {toast} from "react-toastify";

interface Props {
	user: User;
	users: User[];
	linkedCorporate?: CorporateUser | MasterCorporateUser;
}

export default function StudentDashboard({user, users, linkedCorporate}: Props) {
	const {gradingSystem} = useGradingSystem();
	const {data: stats} = useFilterRecordsByUser<Stat[]>(user.id, !user?.id);
	const {assignments, isLoading: isAssignmentsLoading, reload: reloadAssignments} = useAssignments({assignees: user?.id});
	const {invites, isLoading: isInvitesLoading, reload: reloadInvites} = useInvites({to: user.id});

	const router = useRouter();

	const setExams = useExamStore((state) => state.setExams);
	const setShowSolutions = useExamStore((state) => state.setShowSolutions);
	const setUserSolutions = useExamStore((state) => state.setUserSolutions);
	const setSelectedModules = useExamStore((state) => state.setSelectedModules);
	const setAssignment = useExamStore((state) => state.setAssignment);

	const startAssignment = (assignment: Assignment) => {
		const examPromises = assignment.exams.filter((e) => e.assignee === user.id).map((e) => getExamById(e.module, e.id));

		Promise.all(examPromises).then((exams) => {
			if (exams.every((x) => !!x)) {
				setUserSolutions([]);
				setShowSolutions(false);
				setExams(exams.map((x) => x!).sort(sortByModule));
				setSelectedModules(
					exams
						.map((x) => x!)
						.sort(sortByModule)
						.map((x) => x!.module),
				);
				setAssignment(assignment);

				router.push("/exercises");
			}
		});
	};

	return (
		<>
			{linkedCorporate && (
				<div className="absolute right-4 top-4 rounded-lg bg-neutral-200 px-2 py-1">
					Linked to: <b>{linkedCorporate?.corporateInformation?.companyInformation.name || linkedCorporate.name}</b>
				</div>
			)}
			<ProfileSummary
				user={user}
				items={[
					{
						icon: <BsFileEarmarkText className="w-6 h-6 md:w-8 md:h-8 text-mti-red-light" />,
						value: countFullExams(stats),
						label: "Exams",
						tooltip: "Number of all conducted completed exams",
					},
					{
						icon: <BsPencil className="w-6 h-6 md:w-8 md:h-8 text-mti-red-light" />,
						value: countExamModules(stats),
						label: "Modules",
						tooltip: "Number of all exam modules performed including Level Test",
					},
					{
						icon: <BsStar className="text-mti-red-light h-6 w-6 md:h-8 md:w-8" />,
						value: `${stats.length > 0 ? averageScore(stats) : 0}%`,
						label: "Average Score",
						tooltip: "Average success rate for questions responded",
					},
				]}
			/>

			{/* Bio */}
			<section className="flex flex-col gap-1 md:gap-3">
				<span className="text-lg font-bold">Bio</span>
				<span className="text-mti-gray-taupe">
					{user.bio || "Your bio will appear here, you can change it by clicking on your name in the top right corner."}
				</span>
			</section>

			{/* Assignments */}
			<section className="flex flex-col gap-1 md:gap-3">
				<div className="flex items-center gap-4">
					<div
						onClick={reloadAssignments}
						className="text-mti-purple-light hover:text-mti-purple-dark flex cursor-pointer items-center gap-2 transition duration-300 ease-in-out">
						<span className="text-mti-black text-lg font-bold">Assignments</span>
						<BsArrowRepeat className={clsx("text-xl", isAssignmentsLoading && "animate-spin")} />
					</div>
				</div>
				<span className="text-mti-gray-taupe scrollbar-hide flex gap-8 overflow-x-scroll">
					{assignments.filter((a) => moment(a.endDate).isSameOrAfter(moment())).length === 0 &&
						"Assignments will appear here. It seems that for now there are no assignments for you."}
					{assignments
						.filter((a) => moment(a.endDate).isSameOrAfter(moment()))
						.sort((a, b) => moment(a.startDate).diff(b.startDate))
						.map((assignment) => (
							<div
								className={clsx(
									"border-mti-gray-anti-flash flex min-w-[300px] flex-col gap-6 rounded-xl border p-4",
									assignment.results.map((r) => r.user).includes(user.id) && "border-mti-green-light",
								)}
								key={assignment.id}>
								<div className="flex flex-col gap-1">
									<h3 className="text-mti-black/90 text-xl font-semibold">{assignment.name}</h3>
									<span className="flex justify-between gap-1">
										<span>{moment(assignment.startDate).format("DD/MM/YY, HH:mm")}</span>
										<span>-</span>
										<span>{moment(assignment.endDate).format("DD/MM/YY, HH:mm")}</span>
									</span>
								</div>
								<div className="flex w-full items-center justify-between">
									<div className="-md:mt-2 grid w-fit min-w-[104px] grid-cols-2 place-items-center justify-center gap-2">
										{assignment.exams
											.filter((e) => e.assignee === user.id)
											.map((e) => e.module)
											.sort(sortByModuleName)
											.map((module) => (
												<div
													key={module}
													data-tip={capitalize(module)}
													className={clsx(
														"-md:px-4 tooltip flex w-fit items-center gap-2 rounded-xl py-2 text-white md:px-2 xl:px-4",
														module === "reading" && "bg-ielts-reading",
														module === "listening" && "bg-ielts-listening",
														module === "writing" && "bg-ielts-writing",
														module === "speaking" && "bg-ielts-speaking",
														module === "level" && "bg-ielts-level",
													)}>
													{module === "reading" && <BsBook className="h-4 w-4" />}
													{module === "listening" && <BsHeadphones className="h-4 w-4" />}
													{module === "writing" && <BsPen className="h-4 w-4" />}
													{module === "speaking" && <BsMegaphone className="h-4 w-4" />}
													{module === "level" && <BsClipboard className="h-4 w-4" />}
												</div>
											))}
									</div>
									{!assignment.results.map((r) => r.user).includes(user.id) && (
										<>
											<div
												className="tooltip flex h-full w-full items-center justify-end pl-8 md:hidden"
												data-tip="Your screen size is too small to perform an assignment">
												<Button disabled={!assignment.start} className="h-full w-full !rounded-xl" variant="outline">
													Start
												</Button>
											</div>
											<Button
												disabled={!assignment.start}
												className="-md:hidden h-full w-full max-w-[50%] !rounded-xl"
												onClick={() => startAssignment(assignment)}
												variant="outline">
												Start
											</Button>
										</>
									)}
									{assignment.results.map((r) => r.user).includes(user.id) && (
										<Button
											onClick={() => router.push("/record")}
											color="green"
											className="-md:hidden h-full w-full max-w-[50%] !rounded-xl"
											variant="outline">
											Submitted
										</Button>
									)}
								</div>
							</div>
						))}
				</span>
			</section>

			{/* Invites */}
			{invites.length > 0 && (
				<section className="flex flex-col gap-1 md:gap-3">
					<div className="flex items-center gap-4">
						<div
							onClick={reloadInvites}
							className="text-mti-purple-light hover:text-mti-purple-dark flex cursor-pointer items-center gap-2 transition duration-300 ease-in-out">
							<span className="text-mti-black text-lg font-bold">Invites</span>
							<BsArrowRepeat className={clsx("text-xl", isInvitesLoading && "animate-spin")} />
						</div>
					</div>
					<span className="text-mti-gray-taupe scrollbar-hide flex gap-8 overflow-x-scroll">
						{invites.map((invite) => (
							<InviteCard key={invite.id} invite={invite} users={users} reload={reloadInvites} />
						))}
					</span>
				</section>
			)}

			{/* Score History */}
			<section className="flex flex-col gap-3">
				<span className="text-lg font-bold">Score History</span>
				<div className="-md:grid-rows-4 grid gap-6 md:grid-cols-2">
					{MODULE_ARRAY.map((module) => {
						const desiredLevel = user.desiredLevels[module] || 9;
						const level = user.levels[module] || 0;
						return (
							<div className="border-mti-gray-anti-flash flex flex-col gap-2 rounded-xl border p-4" key={module}>
								<div className="flex items-center gap-2 md:gap-3">
									<div className="bg-mti-gray-smoke flex h-8 w-8 items-center justify-center rounded-lg md:h-12 md:w-12 md:rounded-xl">
										{module === "reading" && <BsBook className="text-ielts-reading h-4 w-4 md:h-5 md:w-5" />}
										{module === "listening" && <BsHeadphones className="text-ielts-listening h-4 w-4 md:h-5 md:w-5" />}
										{module === "writing" && <BsPen className="text-ielts-writing h-4 w-4 md:h-5 md:w-5" />}
										{module === "speaking" && <BsMegaphone className="text-ielts-speaking h-4 w-4 md:h-5 md:w-5" />}
										{module === "level" && <BsClipboard className="text-ielts-level h-4 w-4 md:h-5 md:w-5" />}
									</div>
									<div className="flex w-full justify-between">
										<span className="text-sm font-bold md:font-extrabold">{capitalize(module)}</span>
										<span className="text-mti-gray-dim text-sm font-normal">
											{module === "level" && !!gradingSystem && `English Level: ${getGradingLabel(level, gradingSystem.steps)}`}
											{module !== "level" && `Level ${level} / Level 9 (Desired Level: ${desiredLevel})`}
										</span>
									</div>
								</div>
								<div className="md:pl-14">
									<ProgressBar
										color={module}
										label=""
										mark={module === "level" ? undefined : Math.round((desiredLevel * 100) / 9)}
										markLabel={`Desired Level: ${desiredLevel}`}
										percentage={module === "level" ? level : Math.round((level * 100) / 9)}
										className="h-2 w-full"
									/>
								</div>
							</div>
						);
					})}
				</div>
			</section>
		</>
	);
}
