// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next";
import client from "@/lib/mongodb";
import { withIronSessionApiRoute } from "iron-session/next";
import { sessionOptions } from "@/lib/session";
import axios, { AxiosResponse } from "axios";
import { Stat } from "@/interfaces/user";
import { writingReverseMarking } from "@/utils/score";

interface Body {
	question: string;
	answer: string;
	task: 1 | 2;
	id: string;
}

function delay(ms: number) {
	return new Promise((resolve) => setTimeout(resolve, ms));
}

const db = client.db(process.env.MONGODB_DB);

export default withIronSessionApiRoute(handler, sessionOptions);

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

	res.status(200).json(null);

	console.log("🌱 - Still processing");
	const backendRequest = await evaluate(req.body as Body);
	console.log("🌱 - Process complete");

	const correspondingStat = await getCorrespondingStat(req.body.id, 1);

	const solutions = correspondingStat.solutions.map((x) => ({ ...x, evaluation: backendRequest.data }));
	await db.collection("stats").updateOne(
		{ id: (req.body as Body).id },
		{
			$set: {
				id: (req.body as Body).id,
				solutions,
				score: {
					correct: writingReverseMarking[backendRequest.data.overall],
					total: 100,
					missing: 0,
				},
				isDisabled: false,
			}
		},
		{ upsert: true },
	);
	console.log("🌱 - Updated the DB");
}

async function getCorrespondingStat(id: string, index: number): Promise<Stat> {
	console.log(`🌱 - Try number ${index} - ${id}`);
	const correspondingStat = await db.collection("stats").findOne<Stat>({ id: id });

	if (correspondingStat) return correspondingStat;

	await delay(3 * 10000);
	return getCorrespondingStat(id, index + 1);
}

async function evaluate(body: Body): Promise<AxiosResponse> {
	const taskNumber = body.task.toString() !== "1" && body.task.toString() !== "2" ? "1" : body.task.toString();

	const backendRequest = await axios.post(`${process.env.BACKEND_URL}/writing_task${taskNumber}`, body as Body, {
		headers: {
			Authorization: `Bearer ${process.env.BACKEND_JWT}`,
		},
	});

	if (typeof backendRequest.data === "string") return evaluate(body);
	return backendRequest;
}
