import ProgressBar from "@/components/Low/ProgressBar";
import useUsers from "@/hooks/useUsers";
import {Module} from "@/interfaces";
import {Assignment} from "@/interfaces/results";
import {calculateBandScore} from "@/utils/score";
import clsx from "clsx";
import moment from "moment";
import {BsBook, BsClipboard, BsHeadphones, BsMegaphone, BsPen} from "react-icons/bs";
import {usePDFDownload} from "@/hooks/usePDFDownload";
import {useAssignmentArchive} from "@/hooks/useAssignmentArchive";
import {uniqBy} from "lodash";
import {useAssignmentUnarchive} from "@/hooks/useAssignmentUnarchive";
import {useAssignmentRelease} from "@/hooks/useAssignmentRelease";
import {getUserName} from "@/utils/users";
import {User} from "@/interfaces/user";

interface Props {
	users: User[];
	onClick?: () => void;
	allowDownload?: boolean;
	reload?: Function;
	allowArchive?: boolean;
	allowUnarchive?: boolean;
	allowExcelDownload?: boolean;
}

export default function AssignmentCard({
	id,
	name,
	assigner,
	startDate,
	endDate,
	assignees,
	results,
	exams,
	archived,
	onClick,
	allowDownload,
	reload,
	allowArchive,
	allowUnarchive,
	allowExcelDownload,
	users,
	released,
}: Assignment & Props) {
	const renderPdfIcon = usePDFDownload("assignments");
	const renderExcelIcon = usePDFDownload("assignments", "excel");
	const renderArchiveIcon = useAssignmentArchive(id, reload);
	const renderUnarchiveIcon = useAssignmentUnarchive(id, reload);
	const renderReleaseIcon = useAssignmentRelease(id, reload);


	const calculateAverageModuleScore = (module: Module) => {
		const resultModuleBandScores = results.map((r) => {
			const moduleStats = r.stats.filter((s) => s.module === module);

			const correct = moduleStats.reduce((acc, curr) => acc + curr.score.correct, 0);
			const total = moduleStats.reduce((acc, curr) => acc + curr.score.total, 0);
			return calculateBandScore(correct, total, module, r.type);
		});

		return resultModuleBandScores.length === 0 ? -1 : resultModuleBandScores.reduce((acc, curr) => acc + curr, 0) / results.length;
	};

	const uniqModules = uniqBy(exams, (x) => x.module);

	const shouldRenderPDF = () => {
		if(released && allowDownload) {
			// in order to be downloadable, the assignment has to be released
			// the component should have the allowDownload prop
			// and the assignment should not have the level module
			return uniqModules.every(({ module }) => module !== 'level');
		}

		return false;
	}

	const shouldRenderExcel = () => {
		if(released && allowExcelDownload) {
			// in order to be downloadable, the assignment has to be released
			// the component should have the allowExcelDownload prop
			// and the assignment should have the level module
			return uniqModules.some(({ module }) => module === 'level');
		}

		return false;
	}

	return (
		<div
			onClick={onClick}
			className="border-mti-gray-platinum flex h-fit w-[350px] cursor-pointer flex-col gap-6 rounded-xl border bg-white p-4 transition duration-300 ease-in-out hover:drop-shadow">
			<div className="flex flex-col gap-3">
				<div className="flex flex-row justify-between">
					<h3 className="text-xl font-semibold">{name}</h3>
					<div className="flex gap-2">
						{shouldRenderPDF() && renderPdfIcon(id, "text-mti-gray-dim", "text-mti-gray-dim")}
						{shouldRenderExcel() && renderExcelIcon(id, "text-mti-gray-dim", "text-mti-gray-dim")}
						{allowArchive && !archived && renderArchiveIcon("text-mti-gray-dim", "text-mti-gray-dim")}
						{allowUnarchive && archived && renderUnarchiveIcon("text-mti-gray-dim", "text-mti-gray-dim")}
						{!released && renderReleaseIcon("text-mti-gray-dim", "text-mti-gray-dim")}
					</div>
				</div>
				<ProgressBar
					color={results.length / assignees.length < 0.5 ? "red" : "purple"}
					percentage={(results.length / assignees.length) * 100}
					label={`${results.length}/${assignees.length}`}
					className="h-5"
					textClassName={results.length / assignees.length < 0.5 ? "!text-mti-gray-dim font-light" : "text-white"}
				/>
			</div>
			<div className="flex flex-col gap-1">
				<span className="flex justify-between gap-1">
					<span>{moment(startDate).format("DD/MM/YY, HH:mm")}</span>
					<span>-</span>
					<span>{moment(endDate).format("DD/MM/YY, HH:mm")}</span>
				</span>
				<span>Assigner: {getUserName(users.find((x) => x.id === assigner))}</span>
			</div>
			<div className="-md:mt-2 grid w-full grid-cols-4 place-items-start gap-2">
				{uniqModules.map(({module}) => (
					<div
						key={module}
						className={clsx(
							"-md:px-4 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" />}
						{calculateAverageModuleScore(module) > -1 && (
							<span className="text-sm">{calculateAverageModuleScore(module).toFixed(1)}</span>
						)}
					</div>
				))}
			</div>
		</div>
	);
}
