import { AuthUser } from "@/contexts/auth/domain";
import { composeMiddleware, generateExpressError } from "@/contexts/common/infrastructure/express";
import { ensureIdIsValid } from "@shared/contexts";
import { NextFunction, Request, Response } from "express";
import httpStatus from "http-status";
import passport from "passport";

interface AuthenticatedRequest extends Request {
  user?: AuthUser;
}

export const checkUser = composeMiddleware([
  passport.authenticate("local-jwt", {
    session: false,
  }),
  (req: Request, res: Response, next: NextFunction) => {
    const _req = req as AuthenticatedRequest;
    const user = <AuthUser>_req.user;

    if (!user || !user.isUser) {
      return generateExpressError(req, res, httpStatus.UNAUTHORIZED);
    }
    return next();
  },
]);

export const checkisAdmin = composeMiddleware([
  passport.authenticate("local-jwt", {
    session: false,
  }),
  (req: Request, res: Response, next: NextFunction) => {
    const _req = req as AuthenticatedRequest;
    const user = <AuthUser>_req.user;

    if (!user || !user.isAdmin) {
      generateExpressError(req, res, httpStatus.UNAUTHORIZED);
    }
    return next();
  },
]);

export const checkAdminOrSelf = composeMiddleware([
  passport.authenticate("local-jwt", {
    session: false,
  }),
  (req: Request, res: Response, next: NextFunction) => {
    const _req = req as AuthenticatedRequest;
    const user = <AuthUser>_req.user;

    const { userId } = req.params;

    if (user && user.isAdmin) {
      return next();
    }

    if (user && user.isUser && userId) {
      const paramIdOrError = ensureIdIsValid(userId);
      if (paramIdOrError.isSuccess && user.id.equals(paramIdOrError.object)) {
        return next();
      }
    }

    return generateExpressError(req, res, httpStatus.UNAUTHORIZED);
  },
]);
