import { NextFunction, Request, Response } from "express";
import jwt from "jsonwebtoken";
import dotenv from "dotenv";
import { authBasicRoute } from "../api/endpoints/AuthRestResource.js";
import { AuthPayload } from "../api/dtos/AuthPayload.js";
import {HttpStatusCode} from "../api/apiHelpers/HttpStatusCodes.js";

dotenv.config();

declare global {
  namespace Express {
    interface Request {
      currentUser?: AuthPayload;
    }
  }
}

const JWT_SECRET = process.env.JWT_SECRET;

if (!JWT_SECRET) {
  throw new Error("JWT_SECRET not defined");
}

export const authentication = (
  req: Request,
  res: Response,
  next: NextFunction
) => {
   // allow unauthenticated access to auth routes
  if (req.path.startsWith(authBasicRoute)) {
    return next();
  }

  const header = req.headers.authorization;
  if (!header) {
    return res.status(HttpStatusCode.UNAUTHORIZED).json({ message: "Unauthorized" });
  }

  const token = header.split(" ")[1];
  if (!token) {
    return res.status(HttpStatusCode.UNAUTHORIZED).json({ message: "Unauthorized" });
  }

  const JWT_SECRET = process.env.JWT_SECRET;
  if (!JWT_SECRET) {
    throw new Error("JWT_SECRET not defined");
  }

  try {
    req.currentUser = jwt.verify(token, JWT_SECRET) as AuthPayload;
    next();
  } catch {
    return res.status(HttpStatusCode.UNAUTHORIZED).json({ message: "Unauthorized" });
  }
};
