import { NextRequest, NextResponse } from "next/server";
import { Role } from "./helper";

export type AuthResult = {
  response: NextResponse;
  role: Role;
};

export async function authenticate(
  request: NextRequest,
): Promise<AuthResult | null> {
  const accessToken = request.cookies.get("accessToken")?.value;
  const refreshToken = request.cookies.get("refreshToken")?.value;

  if (!accessToken) {
    return null;
  }

  const tokenRes = await fetch(`${process.env.APP_URL}/auth/check-expiry`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      access_token: accessToken,
    }),
  });

  if (!tokenRes.ok) {
    return null;
  }

  const data = await tokenRes.json();

  const userRole = data?.data?.role?.[0] ?? Role.USER;

  if (!data?.data?.isExpired) {
    return {
      response: NextResponse.next(),
      role: userRole,
    };
  }

  const refreshRes = await fetch(`${process.env.APP_URL}/auth/refresh-token`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      refreshToken,
    }),
  });

  if (!refreshRes.ok) {
    const data = await refreshRes.json();
    return null;
  }

  const refreshData = await refreshRes.json();

  const newAccessToken = refreshData.data.accessToken;
  const newRefreshToken = refreshData.data.refreshToken;

  const response = NextResponse.next();

  response.cookies.set("accessToken", newAccessToken, {
    httpOnly: true,
    secure: process.env.NODE_ENV === "production",
    sameSite: "lax",
    path: "/",
  });

  response.cookies.set("refreshToken", newRefreshToken, {
    httpOnly: true,
    secure: process.env.NODE_ENV === "production",
    sameSite: "lax",
    path: "/",
  });

  return {
    response,
    role: userRole,
  };
}
