// middleware/auth.js
const jwt = require('jsonwebtoken');
const { User, Role, Permission } = require('../models');

const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-this';

// Verify JWT token
const verifyToken = async (req, res, next) => {
  try {
    const token = req.headers.authorization?.split(' ')[1] || req.cookies?.token;
    
    if (!token) {
      return res.status(401).json({ error: 'No token provided' });
    }

    const decoded = jwt.verify(token, JWT_SECRET);
    const user = await User.findByPk(decoded.id, {
      include: [{
        model: Role,
        include: [Permission]
      }]
    });

    if (!user || !user.isActive) {
      return res.status(401).json({ error: 'User not found or inactive' });
    }

    req.user = user;
    next();
  } catch (error) {
    return res.status(401).json({ error: 'Invalid or expired token' });
  }
};

// Check if user has required permission
const checkPermission = (module, action) => {
  return async (req, res, next) => {
    try {
      const user = req.user;
      
      // Admin has all permissions
      if (user.Role.name === 'Admin') {
        return next();
      }

      // Check if user's role has the required permission
      const hasPermission = user.Role.Permissions.some(permission => {
        return (permission.module === module || permission.module === 'all') &&
               (permission.action === action || permission.action === 'manage');
      });

      if (!hasPermission) {
        return res.status(403).json({ error: 'Insufficient permissions' });
      }

      next();
    } catch (error) {
      return res.status(500).json({ error: 'Permission check failed' });
    }
  };
};

// Role-based middleware
const requireRole = (...roles) => {
  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({ error: 'Unauthorized' });
    }

    if (!roles.includes(req.user.Role.name)) {
      return res.status(403).json({ error: 'Access denied' });
    }

    next();
  };
};

// Generate JWT token
const generateToken = (userId) => {
  return jwt.sign({ id: userId }, JWT_SECRET, { expiresIn: '7d' });
};

module.exports = {
  verifyToken,
  checkPermission,
  requireRole,
  generateToken
};



