/**
 * ========================================
 * MIDDLEWARE DE VERIFICACIÓN DE PERMISOS
 * ========================================
 *
 * Este middleware verifica si el usuario autenticado tiene
 * permisos para acceder a un recurso con una acción específica.
 *
 * FLUJO:
 * 1. requireAuth → Verifica token y adjunta req.user
 * 2. checkPermission → Verifica permisos del usuario
 * 3. Ruta → Se ejecuta solo si tiene permiso
 *
 * USO:
 *   router.get('/metas',
 *     requireAuth,
 *     checkPermission(RESOURCES.GOALS, ACTIONS.LIST),
 *     async (req, res) => { ... }
 *   );
 */

const { canAccess } = require('../config/permissions');

/**
 * ========================================
 * checkPermission
 * ========================================
 * Factory function que retorna un middleware de verificación de permisos
 *
 * @param {string} resource - El recurso a verificar (ej: 'goals')
 * @param {string} action - La acción a verificar (ej: 'read', 'create')
 * @returns {Function} Middleware de Express
 *
 * EJEMPLO:
 *   const { RESOURCES, ACTIONS } = require('../config/permissions');
 *   const checkPermission = require('../middleware/checkPermission');
 *
 *   router.post('/metas',
 *     requireAuth,
 *     checkPermission(RESOURCES.GOALS, ACTIONS.CREATE),
 *     async (req, res) => {
 *       // Solo llega aquí si tiene permiso
 *     }
 *   );
 */
function checkPermission(resource, action) {
  return (req, res, next) => {
    // 1. Verificar que el usuario esté autenticado
    if (!req.user) {
      return res.status(401).json({
        ok: false,
        error: 'No autenticado. Este middleware requiere requireAuth antes.'
      });
    }

    // 2. Obtener roles del usuario
    // Los roles deben venir en req.user.roles (array)
    const userRoles = req.user.roles || [];

    // 3. Log para debugging
    console.log(`[PERMISOS] Usuario ${req.user.id_usuario} intenta ${action} en ${resource}`);
    console.log(`[PERMISOS] Roles del usuario:`, userRoles);

    // 4. Verificar si tiene permiso
    const hasAccess = canAccess(userRoles, resource, action);

    if (!hasAccess) {
      console.log(`[PERMISOS] ❌ ACCESO DENEGADO`);
      return res.status(403).json({
        ok: false,
        error: 'No tienes permisos para realizar esta acción',
        details: {
          resource,
          action,
          yourRoles: userRoles
        }
      });
    }

    console.log(`[PERMISOS] ✅ ACCESO PERMITIDO`);

    // 5. Tiene permiso, continuar
    next();
  };
}

/**
 * ========================================
 * requireRole
 * ========================================
 * Middleware simplificado que solo verifica si el usuario tiene un rol específico
 *
 * @param {string|Array} allowedRoles - Rol o roles permitidos
 * @returns {Function} Middleware de Express
 *
 * EJEMPLO:
 *   router.get('/admin/metrics',
 *     requireAuth,
 *     requireRole('admin'),
 *     async (req, res) => { ... }
 *   );
 */
function requireRole(allowedRoles) {
  // Normalizar a array
  const roles = Array.isArray(allowedRoles) ? allowedRoles : [allowedRoles];

  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({
        ok: false,
        error: 'No autenticado'
      });
    }

    const userRoles = req.user.roles || [];

    // Verificar si tiene al menos uno de los roles permitidos
    const hasRole = userRoles.some(role => roles.includes(role));

    if (!hasRole) {
      return res.status(403).json({
        ok: false,
        error: 'No tienes el rol necesario para acceder',
        details: {
          requiredRoles: roles,
          yourRoles: userRoles
        }
      });
    }

    next();
  };
}

/**
 * ========================================
 * EXPORTACIÓN
 * ========================================
 */
module.exports = {
  checkPermission,
  requireRole
};
