import { defineMiddleware } from "astro:middleware";
import { errors, jwtVerify } from "jose";

// The key of the JWT cookie value
export const TOKEN = "token";

// The following pages need auth to be accessed
export const PROTECTED_ROUTES = ["/api/chat/reply", "/api/auth/register"];
const secret = new TextEncoder().encode(import.meta.env.SESSION_SECRET);

/**
 * Verify if the client token is valid.
 */
export const verifyAuth = async (token?: string) => {
  if (!token) {
    return {
      status: "unauthorized",
      msg: "Please pass a request token",
    } as const;
  }

  try {
    const jwtVerifyResult = await jwtVerify(token, secret);
    console.log({ jwtVerifyResult });

    return {
      status: "authorized",
      payload: jwtVerifyResult.payload,
      msg: "successfully verified auth token",
    } as const;
  } catch (err) {
    if (err instanceof errors.JOSEError) {
      return { status: "error", msg: err.message } as const;
    }
    return { status: "error", msg: "could not validate auth token" } as const;
  }
};

export const onRequest = defineMiddleware(
  async ({ url, cookies, redirect, locals }, next) => {
    const isDashboard = url.pathname.startsWith("/dashboard");

    if (!isDashboard) return next();

    // Get the token from cookies
    const token = cookies?.get(TOKEN)?.value;
    // Verify the token
    const { status, msg, payload } = await verifyAuth(token);

    console.log({
      token,
      status,
      msg,
      payload,
    });

    // @ts-ignore
    if (!locals.user)
      // @ts-ignore
      locals.user = payload?.user;

    // Ignore auth validation for public routes
    if (!PROTECTED_ROUTES.includes(url.pathname)) {
      if (
        url.pathname.startsWith("/api/auth") ||
        url.pathname.startsWith("/dashboard/register") ||
        url.pathname.startsWith("/dashboard/logout")
      )
        // Respond as usual
        return next();
    }

    // Respond as usual if the user is authorised
    if (status === "authorized")
      if (url.pathname.startsWith("/dashboard/login"))
        return redirect("/dashboard");
      else if (
        // @ts-ignore
        !locals?.user?.isAdmin &&
        url.pathname.startsWith("/dashboard/staffs")
        // ||
        // url.pathname.startsWith("/dashboard/register")
      )
        return redirect("/dashboard");
      else return next();
    else if (status === "error" || status === "unauthorized") {
      if (
        /^\/dashboard\/(login|forgot-password|reset-password)/.test(
          url.pathname
        )
      )
        return next();
      if (
        url.pathname.startsWith("/api/") &&
        PROTECTED_ROUTES.includes(url.pathname)
      ) {
        return new Response(JSON.stringify({ message: msg }), {
          status: 401,
        });
      }
      // Otherwise, this is a standard page. Redirect to the root page for the user to login
      else if (isDashboard) {
        return Response.redirect(new URL("/dashboard/login", url));
      }
    }
    return Response.redirect(new URL("/", url));
  }
);
