const jwt = require('jsonwebtoken');
const { one } = require('../db');

const JWT_SECRET = process.env.DEPRECORE_JWT_SECRET || 'deprecore-local-development-secret';

function publicUser(user) {
  if (!user) return null;
  return {
    id: user.id,
    name: user.name,
    email: user.email,
    role: user.role,
    teamId: user.team_id
  };
}

function tokenFor(user) {
  return jwt.sign({ sub: user.id, role: user.role, teamId: user.team_id }, JWT_SECRET, { expiresIn: '12h' });
}

function requireAuth(req, res, next) {
  const header = req.headers.authorization || '';
  const [, token] = header.split(' ');
  if (!token) return res.status(401).json({ error: 'Authentication required' });

  try {
    const payload = jwt.verify(token, JWT_SECRET);
    const user = one('SELECT * FROM users WHERE id = ? AND status = ?', [payload.sub, 'active']);
    if (!user) return res.status(401).json({ error: 'User is inactive or missing' });
    req.user = user;
    return next();
  } catch {
    return res.status(401).json({ error: 'Invalid or expired token' });
  }
}

function requireRole(...roles) {
  return (req, res, next) => {
    if (!roles.includes(req.user.role)) return res.status(403).json({ error: 'Insufficient access' });
    return next();
  };
}

// Capability-based guard: the user's role must grant at least one of the listed capabilities.
// Required lazily to avoid a load-time cycle (roles -> db -> ...).
function requireCapability(...capabilities) {
  return (req, res, next) => {
    const { capabilitiesForRole } = require('../services/roles');
    const { capabilitySetIncludes } = require('../services/accessControl');
    const granted = capabilitiesForRole(req.user.role);
    if (!capabilities.some((cap) => capabilitySetIncludes(granted, cap))) {
      return res.status(403).json({ error: 'Insufficient access' });
    }
    return next();
  };
}

module.exports = {
  publicUser,
  requireAuth,
  requireCapability,
  requireRole,
  tokenFor
};
