import { NextRequest } from "next/server";
import { sign } from "jsonwebtoken";
import { prisma } from "@repo/db";
import { services } from "../../../../helper/authServices";

export const POST = async (req: NextRequest) => {
	try {
		if (!req.headers.get("content-type")?.includes("application/x-www-form-urlencoded")) {
			return new Response("Unsupported Content-Type", { status: 415 });
		}

		const form = new URLSearchParams(await req.text());
		const accessToken = form.get("token") || form.get("code");
		const clientId = form.get("client_id");
		const clientSecret = form.get("client_secret");

		if (!accessToken) {
			console.log("No access token provided", accessToken);
			return new Response("No access token provided", { status: 400 });
		}

		if (!clientId) {
			console.log("No client ID provided", clientId);
			return new Response("No client ID provided", { status: 400 });
		}

		const service = services.find((s) => s.id === clientId);

		if (!service || service.secret !== clientSecret) {
			console.log("Invalid client ID or secret", clientId, clientSecret);
			return new Response("Invalid client credentials", { status: 401 });
		}

		const accessRequest = await prisma.oAuthToken.findFirst({
			where: {
				accessToken: accessToken,
				clientId: clientId,
			},
			include: {
				user: true,
			},
		});

		if (!accessRequest) {
			console.log("Access token not found", accessToken);
			return new Response("Access token not found", { status: 404 });
		}

		if (new Date().getTime() - accessRequest.createdAt.getTime() > 60 * 1000) {
			await prisma.oAuthToken.delete({
				where: {
					id: accessRequest.id,
				},
			});
			console.log("Code expired", accessRequest.id);
			return new Response("Code expired", { status: 410 });
		}

		const jwt = sign(
			{
				...accessRequest.user,
			},
			process.env.AUTH_HUB_SECRET as string,
			{
				expiresIn: "30d",
			},
		);

		return Response.json({
			access_token: jwt,
			token_type: "Bearer",
		});
	} catch (error) {
		console.error("Error in accessToken route:", error);
		return new Response((error as Error).message || "Internal Server Error", {
			status: 500,
		});
	}
};
