const jwt = require("jsonwebtoken");
const { sendError } = require("../utils/http");
const Session = require("../models/session.model");
const { parseCookieHeader } = require("../utils/cookies");
const { cookieName } = require("../utils/session-cookie");
const { logError } = require("../utils/logger");

async function auth(req, res, next) {
  const header = req.headers.authorization || "";
  const token = header.startsWith("Bearer ") ? header.slice(7).trim() : null;

  if (token) {
    const jwtSecret = process.env.JWT_SECRET;
    if (!jwtSecret) {
      logError(req, "middleware.auth.jwtSecretMissing", new Error("JWT_SECRET is not configured"));
      return sendError(res, 500, "Authentication is unavailable");
    }

    try {
      const decoded = jwt.verify(token, jwtSecret);
      req.user = decoded; // id + role
      return next();
    } catch (err) {
      return sendError(res, 401, "Invalid or expired token");
    }
  }

  try {
    const cookies = parseCookieHeader(req.headers.cookie);
    const sid = cookies[cookieName()];

    if (!sid) {
      return sendError(res, 401, "Missing authentication");
    }

    const session = await Session.getActiveSessionWithUser(sid);
    if (!session) {
      return sendError(res, 401, "Invalid or expired session");
    }

    req.user = {
      id: session.user_id,
      role: session.role,
      username: session.username,
    };
    req.session_id = session.id;

    return next();
  } catch (err) {
    logError(req, "middleware.auth", err);
    return sendError(res, 500, "Authentication check failed");
  }
}

module.exports = auth;
