import {PERMISSIONS} from "@/constants/userPermissions";
import {app, adminApp} from "@/firebase";
import {Group, User} from "@/interfaces/user";
import {sessionOptions} from "@/lib/session";
import {getAuth} from "firebase-admin/auth";
import {withIronSessionApiRoute} from "iron-session/next";
import {NextApiRequest, NextApiResponse} from "next";
import {getPermissions, getPermissionDocs} from "@/utils/permissions.be";
import client from "@/lib/mongodb";
import {getGroupsForUser, getParticipantGroups} from "@/utils/groups.be";

const auth = getAuth(adminApp);
const db = client.db(process.env.MONGODB_DB);

export default withIronSessionApiRoute(user, sessionOptions);

async function user(req: NextApiRequest, res: NextApiResponse) {
	if (req.method === "GET") return get(req, res);
	if (req.method === "DELETE") return del(req, res);

	res.status(404).json(undefined);
}

async function del(req: NextApiRequest, res: NextApiResponse) {
	if (!req.session.user) {
		res.status(401).json({ok: false});
		return;
	}

	const {id} = req.query as {id: string};

	const user = await db.collection("users").findOne<User>({id: req.session.user.id});
	if (!user) {
		res.status(401).json({ok: false});
		return;
	}

	const targetUser = await db.collection("users").findOne<User>({id});
	if (!targetUser) {
		res.status(404).json({ok: false});
		return;
	}

	if (user.type === "corporate" && (targetUser.type === "student" || targetUser.type === "teacher")) {
		const groups = await getGroupsForUser(user.id, targetUser.id);
		await Promise.all([
			...groups
				.filter((x) => x.admin === user.id)
				.map(
					async (x) =>
						await db.collection("groups").updateOne({id: x.id}, {$set: {participants: x.participants.filter((y: string) => y !== id)}}),
				),
		]);

		return;
	}

	await auth.deleteUser(id);
	await db.collection("users").deleteOne({id: targetUser.id});
	await db.collection("codes").deleteMany({userId: targetUser.id});
	await db.collection("groups").deleteMany({admin: targetUser.id});
	await db.collection("stats").deleteMany({user: targetUser.id});

	const groups = await getParticipantGroups(targetUser.id);
	await Promise.all(
		groups.map(
			async (x) => await db.collection("groups").updateOne({id: x.id}, {$set: {participants: x.participants.filter((y: string) => y !== id)}}),
		),
	);

	res.json({ok: true});
}

async function get(req: NextApiRequest, res: NextApiResponse) {
	if (req.session.user) {
		const user = await db.collection("users").findOne<User>({id: req.session.user.id});
		if (!user) {
			res.status(401).json(undefined);
			return;
		}

		await db.collection("users").updateOne({id: user.id}, {$set: {lastLogin: new Date().toISOString()}});

		req.session.user = {
			...user,
			id: req.session.user.id,
			lastLogin: new Date(),
		};
		await req.session.save();

		res.json({...user, id: req.session.user.id});
	} else {
		res.status(401).json(undefined);
	}
}
