import { 
  extractTokenFromRequest, 
  verifyAccessToken 
} from '../../infrastructure/auth/authUtils.js';
import { UserRepository } from '../../infrastructure/repositories/UserRepository.js';

const userRepository = new UserRepository();

/**
 * Authentication Middleware
 * 
 * Ellenőrzi a JWT tokent és beállítja req.user-t
 */
export async function authenticateToken(req, res, next) {
  try {
    // 1. Token kiolvasása (cookie vagy Authorization header)
    const token = extractTokenFromRequest(req);
    
    if (!token) {
      return res.status(401).json({
        success: false,
        error: 'Access token required'
      });
    }

    // 2. Token validálás
    const decoded = verifyAccessToken(token);

    // 3. User lekérése az adatbázisból
    const user = await userRepository.findById(decoded.userId);
    
    if (!user) {
      return res.status(401).json({
        success: false,
        error: 'User not found'
      });
    }

    // 4. User hozzáadása a request objektumhoz
    req.user = user;

    // 5. Továbblépés a következő middleware-re
    next();
  } catch (error) {
    console.error('Authentication error:', error);
    return res.status(401).json({
      success: false,
      error: 'Invalid or expired token'
    });
  }
}

/**
 * Authorization Middleware - Role Check
 * 
 * Ellenőrzi, hogy a usernek megfelel ő role-ja van-e
 * 
 * @param {string[]} allowedRoles - Engedélyezett role-ok listája
 * @returns {Function} Express middleware
 */
export function requireRole(allowedRoles) {
  return (req, res, next) => {
    try {
      // 1. Ellenőrzés: req.user létezik? (authenticateToken után fut)
      if (!req.user) {
        return res.status(401).json({
          success: false,
          error: 'Authentication required'
        });
      }

      // 2. Role check: van-e a usernek megfelelő role-ja?
      if (!allowedRoles.includes(req.user.role)) {
        return res.status(403).json({
          success: false,
          error: 'Insufficient permissions'
        });
      }

      // 3. OK, továbblépés
      next();
    } catch (error) {
      console.error('Authorization error:', error);
      return res.status(403).json({
        success: false,
        error: 'Authorization failed'
      });
    }
  };
}

/**
 * Resource Ownership Check
 * 
 * Ellenőrzi, hogy a user tulajdonosa-e az adott resource-nak
 * VAGY admin role-ja van
 * 
 * @param {Function} getResourceOwnerId - Async függvény ami visszaadja a resource owner ID-t
 * @returns {Function} Express middleware
 */
export function checkOwnership(getResourceOwnerId) {
  return async (req, res, next) => {
    try {
      // 1. User ellenőrzés
      if (!req.user) {
        return res.status(401).json({
          success: false,
          error: 'Authentication required'
        });
      }

      // 2. Resource owner ID lekérése
      const ownerId = await getResourceOwnerId(req);

      if (!ownerId) {
        return res.status(404).json({
          success: false,
          error: 'Resource not found'
        });
      }

      // 3. Ownership ellenőrzés: user tulajdonos VAGY admin
      const isOwner = req.user.id === ownerId;
      const isAdmin = req.user.role === 'ADMIN';

      if (!isOwner && !isAdmin) {
        return res.status(403).json({
          success: false,
          error: 'You do not have permission to access this resource'
        });
      }

      // 4. OK, továbblépés
      next();
    } catch (error) {
      console.error('Ownership check error:', error);
      return res.status(500).json({
        success: false,
        error: 'Ownership verification failed'
      });
    }
  };
}
