/* eslint-disable @next/next/no-img-element */
import UserDisplayList from "@/components/UserDisplayList";
import IconCard from "@/components/IconCard";
import {useAllowedEntities} from "@/hooks/useEntityPermissions";
import {EntityWithRoles} from "@/interfaces/entity";
import {Stat, StudentUser, Type, User} from "@/interfaces/user";
import {sessionOptions} from "@/lib/session";
import {filterBy, mapBy, redirect, serialize} from "@/utils";
import {requestUser} from "@/utils/api";
import {countEntitiesAssignments} from "@/utils/assignments.be";
import {getEntitiesWithRoles} from "@/utils/entities.be";
import {countGroupsByEntities} from "@/utils/groups.be";
import {checkAccess, groupAllowedEntitiesByPermissions} from "@/utils/permissions";
import {groupByExam} from "@/utils/stats";
import {countAllowedUsers, getUsers} from "@/utils/users.be";
import {clsx} from "clsx";
import {withIronSessionSsr} from "iron-session/next";
import moment from "moment";
import Head from "next/head";
import {useRouter} from "next/router";
import {useMemo} from "react";
import {BsBank, BsClock, BsEnvelopePaper, BsPencilSquare, BsPeople, BsPeopleFill, BsPersonFill, BsPersonFillGear} from "react-icons/bs";
import {ToastContainer} from "react-toastify";
import {isAdmin} from "@/utils/users";

interface Props {
	user: User;
	students: StudentUser[];
	latestStudents: User[];
	latestTeachers: User[];
	userCounts: {[key in Type]: number};
	entities: EntityWithRoles[];
	assignmentsCount: number;
	stats: Stat[];
	groupsCount: number;
}

export const getServerSideProps = withIronSessionSsr(async ({req, res}) => {
	const user = await requestUser(req, res);
	if (!user || !user.isVerified) return redirect("/login");

	if (!checkAccess(user, ["admin", "developer", "mastercorporate"])) return redirect("/");

	const entityIDS = mapBy(user.entities, "id") || [];
	const entities = await getEntitiesWithRoles(isAdmin(user) ? undefined : entityIDS);
	const {["view_students"]: allowedStudentEntities, ["view_teachers"]: allowedTeacherEntities} = groupAllowedEntitiesByPermissions(user, entities, [
		"view_students",
		"view_teachers",
	]);

	const allowedStudentEntitiesIDS = mapBy(allowedStudentEntities, "id");

	const entitiesIDS = mapBy(entities, "id") || [];

	const [students, latestStudents, latestTeachers, userCounts, assignmentsCount, groupsCount] = await Promise.all([
		getUsers(
			{type: "student", "entities.id": {$in: allowedStudentEntitiesIDS}},
			10,
			{averageLevel: -1},
			{_id: 0, id: 1, name: 1, email: 1, profilePicture: 1},
		),
		getUsers(
			{type: "student", "entities.id": {$in: allowedStudentEntitiesIDS}},
			10,
			{registrationDate: -1},
			{_id: 0, id: 1, name: 1, email: 1, profilePicture: 1},
		),
		getUsers(
			{
				type: "teacher",
				"entities.id": {$in: mapBy(allowedTeacherEntities, "id")},
			},
			10,
			{registrationDate: -1},
			{_id: 0, id: 1, name: 1, email: 1, profilePicture: 1},
		),
		countAllowedUsers(user, entities),
		countEntitiesAssignments(entitiesIDS, {archived: {$ne: true}}),
		countGroupsByEntities(entitiesIDS),
	]);

	return {
		props: serialize({
			user,
			students,
			latestStudents,
			latestTeachers,
			userCounts,
			entities,
			assignmentsCount,
			groupsCount,
		}),
	};
}, sessionOptions);

export default function Dashboard({
	user,
	students,
	latestStudents,
	latestTeachers,
	userCounts,
	entities,
	assignmentsCount,
	stats = [],
	groupsCount,
}: Props) {
	const totalCount = useMemo(() => userCounts.corporate + userCounts.mastercorporate + userCounts.student + userCounts.teacher, [userCounts]);

	const totalLicenses = useMemo(() => entities.reduce((acc, curr) => acc + parseInt(curr.licenses.toString()), 0), [entities]);

	const router = useRouter();

	const allowedEntityStatistics = useAllowedEntities(user, entities, "view_entity_statistics");
	const allowedStudentPerformance = useAllowedEntities(user, entities, "view_student_performance");

	return (
		<>
			<Head>
				<title>EnCoach</title>
				<meta
					name="description"
					content="A training platform for the IELTS exam provided by the Muscat Training Institute and developed by eCrop."
				/>
				<meta name="viewport" content="width=device-width, initial-scale=1" />
				<link rel="icon" href="/favicon.ico" />
			</Head>
			<ToastContainer />
			<>
				<section className="grid grid-cols-5 place-items-center -md:grid-cols-2 gap-4 text-center">
					<IconCard
						onClick={() => router.push("/users?type=student")}
						Icon={BsPersonFill}
						label="Students"
						value={userCounts.student}
						color="purple"
					/>
					<IconCard
						onClick={() => router.push("/users?type=teacher")}
						Icon={BsPencilSquare}
						label="Teachers"
						value={userCounts.teacher}
						color="purple"
					/>
					<IconCard
						onClick={() => router.push("/users?type=corporate")}
						Icon={BsBank}
						label="Corporate Accounts"
						value={userCounts.corporate}
						color="purple"
					/>
					<IconCard
						Icon={BsBank}
						onClick={() => router.push("/users?type=mastercorporate")}
						label="Master Corporates"
						value={userCounts.mastercorporate}
						color="purple"
					/>
					<IconCard Icon={BsPeople} onClick={() => router.push("/classrooms")} label="Classrooms" value={groupsCount} color="purple" />
					<IconCard
						Icon={BsPeopleFill}
						onClick={() => router.push("/entities")}
						label="Entities"
						value={`${entities.length} - ${totalCount}/${totalLicenses}`}
						color="purple"
					/>
					{allowedStudentPerformance.length > 0 && (
						<IconCard
							Icon={BsPersonFillGear}
							onClick={() => router.push("/users/performance")}
							label="Student Performance"
							value={userCounts.student}
							color="purple"
						/>
					)}
					{allowedEntityStatistics.length > 0 && (
						<IconCard
							Icon={BsPersonFillGear}
							onClick={() => router.push("/statistical")}
							label="Entity Statistics"
							value={allowedEntityStatistics.length}
							color="purple"
						/>
					)}
					<IconCard
						Icon={BsEnvelopePaper}
						onClick={() => router.push("/assignments")}
						label="Assignments"
						value={assignmentsCount}
						className={clsx(allowedEntityStatistics.length === 0 && "col-span-2")}
						color="purple"
					/>
					<IconCard
						Icon={BsClock}
						label="Expiration Date"
						value={user.subscriptionExpirationDate ? moment(user.subscriptionExpirationDate).format("DD/MM/yyyy") : "Unlimited"}
						color="rose"
					/>
				</section>

				<section className="grid grid-cols-1 md:grid-cols-2 gap-4 w-full justify-between">
					<UserDisplayList users={latestStudents} title="Latest Students" />
					<UserDisplayList users={latestTeachers} title="Latest Teachers" />
					<UserDisplayList users={students} title="Highest level students" />
					<UserDisplayList
						users={students.sort(
							(a, b) =>
								Object.keys(groupByExam(filterBy(stats, "user", b))).length -
								Object.keys(groupByExam(filterBy(stats, "user", a))).length,
						)}
						title="Highest exam count students"
					/>
				</section>
			</>
		</>
	);
}
