/* eslint-disable @next/next/no-img-element */
import Layout from "@/components/High/Layout";
import UserDisplayList from "@/components/UserDisplayList";
import IconCard from "@/dashboards/IconCard";
import { Module } from "@/interfaces";
import { EntityWithRoles } from "@/interfaces/entity";
import { Assignment } from "@/interfaces/results";
import { Group, Stat, User } from "@/interfaces/user";
import { sessionOptions } from "@/lib/session";
import { dateSorter, filterBy, mapBy, redirect, serialize } from "@/utils";
import { requestUser } from "@/utils/api";
import { getAssignments, getEntitiesAssignments } from "@/utils/assignments.be";
import { getEntitiesWithRoles } from "@/utils/entities.be";
import { getGroups, getGroupsByEntities } from "@/utils/groups.be";
import { checkAccess } from "@/utils/permissions";
import { calculateAverageLevel, calculateBandScore } from "@/utils/score";
import { groupByExam } from "@/utils/stats";
import { getStatsByUsers } from "@/utils/stats.be";
import { getEntitiesUsers, getUsers } from "@/utils/users.be";
import { withIronSessionSsr } from "iron-session/next";
import { uniqBy } from "lodash";
import moment from "moment";
import Head from "next/head";
import Link from "next/link";
import { useRouter } from "next/router";
import { useMemo } from "react";
import {
  BsBank,
  BsClipboard2Data,
  BsClock,
  BsEnvelopePaper,
  BsPaperclip,
  BsPencilSquare,
  BsPeople,
  BsPeopleFill,
  BsPersonFill,
  BsPersonFillGear,
} from "react-icons/bs";
import { ToastContainer } from "react-toastify";

interface Props {
  user: User;
  users: User[];
  entities: EntityWithRoles[];
  assignments: Assignment[];
  stats: Stat[];
  groups: Group[];
}

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

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

  const users = await getUsers();
  const entities = await getEntitiesWithRoles();
  const assignments = await getAssignments();
  const stats = await getStatsByUsers(users.map((u) => u.id));
  const groups = await getGroups();

  return { props: serialize({ user, users, entities, assignments, stats, groups }) };
}, sessionOptions);

export default function Dashboard({ user, users, entities, assignments, stats, groups }: Props) {
  const students = useMemo(() => users.filter((u) => u.type === "student"), [users]);
  const teachers = useMemo(() => users.filter((u) => u.type === "teacher"), [users]);
  const corporates = useMemo(() => users.filter((u) => u.type === "corporate"), [users]);
  const masterCorporates = useMemo(() => users.filter((u) => u.type === "mastercorporate"), [users]);

  const router = useRouter();

  const averageLevelCalculator = (studentStats: Stat[]) => {
    const formattedStats = studentStats
      .map((s) => ({
        focus: students.find((u) => u.id === s.user)?.focus,
        score: s.score,
        module: s.module,
      }))
      .filter((f) => !!f.focus);
    const bandScores = formattedStats.map((s) => ({
      module: s.module,
      level: calculateBandScore(s.score.correct, s.score.total, s.module, s.focus!),
    }));

    const levels: { [key in Module]: number } = {
      reading: 0,
      listening: 0,
      writing: 0,
      speaking: 0,
      level: 0,
    };
    bandScores.forEach((b) => (levels[b.module] += b.level));

    return calculateAverageLevel(levels);
  };

  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 />
      <Layout user={user}>
        <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={students.length}
            color="purple"
          />
          <IconCard
            onClick={() => router.push("/users?type=teacher")}
            Icon={BsPencilSquare}
            label="Teachers"
            value={teachers.length}
            color="purple"
          />
          <IconCard
            Icon={BsBank}
            onClick={() => router.push("/users?type=corporate")}
            label="Corporates"
            value={corporates.length}
            color="purple"
          />
          <IconCard
            Icon={BsBank}
            onClick={() => router.push("/users?type=mastercorporate")}
            label="Master Corporates"
            value={masterCorporates.length}
            color="purple"
          />
          <IconCard
          	Icon={BsPeople}
           	onClick={() => router.push("/classrooms")}
            label="Classrooms"
            value={groups.length}
            color="purple"
          />
          <IconCard Icon={BsPeopleFill}
          	onClick={() => router.push("/entities")}
           	label="Entities"
            value={entities.length}
            color="purple"
          />
          <IconCard Icon={BsClipboard2Data} label="Exams Performed" value={uniqBy(stats, "exam").length} color="purple" />
          <IconCard Icon={BsPaperclip} label="Average Level" value={averageLevelCalculator(stats).toFixed(1)} color="purple" />
          <IconCard Icon={BsPersonFillGear}
	          onClick={() => router.push("/users/performance")}
	          label="Student Performance"
						value={students.length}
						color="purple"
					/>
          <IconCard
            Icon={BsEnvelopePaper}
            onClick={() => router.push("/assignments")}
            label="Assignments"
            value={assignments.filter((a) => !a.archived).length}
            color="purple"
          />
        </section>

        <section className="grid grid-cols-1 md:grid-cols-2 gap-4 w-full justify-between">
          <UserDisplayList
            users={students.sort((a, b) => dateSorter(a, b, "desc", "registrationDate"))}
            title="Latest Students"
          />
          <UserDisplayList
            users={teachers.sort((a, b) => dateSorter(a, b, "desc", "registrationDate"))}
            title="Latest Teachers"
          />
          <UserDisplayList
            users={students.sort((a, b) => calculateAverageLevel(b.levels) - calculateAverageLevel(a.levels))}
            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>
      </Layout>
    </>
  );
}
