// FILE: backend/src/middleware/auth.js

import jwt from "jsonwebtoken";
import { config } from "../config.js";
import { User, Role, UserRole } from "../db/sequelize.js";

export function signAccessToken(payload) {
  return jwt.sign(payload, config.JWT.SECRET, {
    expiresIn: config.JWT.EXPIRES_IN,
  });
}
export function signRefreshToken(payload) {
  return jwt.sign(payload, config.JWT.REFRESH_SECRET, {
    expiresIn: config.JWT.REFRESH_EXPIRES_IN,
  });
}

export function extractToken(req) {
  // ให้คุกกี้มาก่อน แล้วค่อย Bearer (รองรับทั้งสองทาง)
  const cookieTok = req.cookies?.access_token || null;
  if (cookieTok) return cookieTok;
  const hdr = req.headers.authorization || "";
  return hdr.startsWith("Bearer ") ? hdr.slice(7) : null;
}

export function requireAuth(req, res, next) {
  if (req.path === "/health") return next(); // อนุญาต health เสมอ
  const token = extractToken(req);
  if (!token) return res.status(401).json({ error: "Missing token" });

  try {
    req.user = jwt.verify(token, config.JWT.SECRET);
    next();
  } catch {
    return res.status(401).json({ error: "Invalid/Expired token" });
  }
}
// ใช้กับเส้นทางที่ login แล้วจะ enrich ต่อได้ แต่ไม่บังคับ
export function optionalAuth(req, _res, next) {
  const token = extractToken(req);
  if (!token) return next();
  try {
    req.user = jwt.verify(token, config.JWT.SECRET);
  } catch {}
  next();
}

export async function enrichRoles(req, _res, next) {
  if (!req.user?.user_id) return next();
  const rows = await UserRole.findAll({
    where: { user_id: req.user.user_id },
    include: [{ model: Role }],
  }).catch(() => []);
  req.user.roles = rows.map((r) => r.role?.role_name).filter(Boolean);
  next();
}

export function hasPerm(req, perm) {
  const set = new Set(req?.user?.permissions || []);
  return set.has(perm);
}
