import permissionService from '../services/permissionService.js';

/**
 * Authorization Middleware
 * Checks if user has permission to access a resource
 */

/**
 * Check if user has permission for a specific resource and action
 * @param {string} resource - Resource name (diary, members, teams, etc.)
 * @param {string} action - Action type (read, write, delete)
 * @returns {Function} Express middleware function
 */
export const authorize = (resource, action = 'read') => {
  return async (req, res, next) => {
    try {
      const userId = req.user?.id;
      
      if (!userId) {
        return res.status(401).json({ error: 'Nicht authentifiziert' });
      }

      // Get clubId from various possible sources
      const clubId =
        req.params.clubId ??
        req.params.clubid ??
        req.params.id ??
        req.body.clubId ??
        req.body.clubid ??
        req.query.clubId ??
        req.query.clubid;

      if (!clubId) {
        return res.status(400).json({ error: 'Club-ID fehlt' });
      }

      // Check permission
      const hasPermission = await permissionService.hasPermission(
        userId,
        parseInt(clubId),
        resource,
        action
      );

      if (!hasPermission) {
        return res.status(403).json({ 
          error: 'Keine Berechtigung',
          details: `Fehlende Berechtigung: ${resource}.${action}`
        });
      }

      // Store permissions in request for later use
      const userPermissions = await permissionService.getUserClubPermissions(
        userId,
        parseInt(clubId)
      );
      req.userPermissions = userPermissions;

      next();
    } catch (error) {
      console.error('Authorization error:', error);
      res.status(500).json({ error: 'Fehler bei der Berechtigungsprüfung' });
    }
  };
};

/**
 * Check if user is club owner
 * @returns {Function} Express middleware function
 */
export const requireOwner = () => {
  return async (req, res, next) => {
    try {
      const userId = req.user?.id;
      
      if (!userId) {
        return res.status(401).json({ error: 'Nicht authentifiziert' });
      }

      const clubId =
        req.params.clubId ??
        req.params.clubid ??
        req.params.id ??
        req.body.clubId ??
        req.body.clubid ??
        req.query.clubId ??
        req.query.clubid;

      if (!clubId) {
        return res.status(400).json({ error: 'Club-ID fehlt' });
      }

      const userPermissions = await permissionService.getUserClubPermissions(
        userId,
        parseInt(clubId)
      );

      if (!userPermissions || !userPermissions.isOwner) {
        return res.status(403).json({ 
          error: 'Keine Berechtigung',
          details: 'Nur der Club-Ersteller hat Zugriff'
        });
      }

      req.userPermissions = userPermissions;
      next();
    } catch (error) {
      console.error('Owner check error:', error);
      res.status(500).json({ error: 'Fehler bei der Berechtigungsprüfung' });
    }
  };
};

/**
 * Check if user is admin (owner or admin role)
 * @returns {Function} Express middleware function
 */
export const requireAdmin = () => {
  return async (req, res, next) => {
    try {
      const userId = req.user?.id;
      
      if (!userId) {
        return res.status(401).json({ error: 'Nicht authentifiziert' });
      }

      const clubId =
        req.params.clubId ??
        req.params.clubid ??
        req.params.id ??
        req.body.clubId ??
        req.body.clubid ??
        req.query.clubId ??
        req.query.clubid;

      if (!clubId) {
        return res.status(400).json({ error: 'Club-ID fehlt' });
      }

      const userPermissions = await permissionService.getUserClubPermissions(
        userId,
        parseInt(clubId)
      );

      if (!userPermissions || (!userPermissions.isAdmin && !userPermissions.isOwner)) {
        return res.status(403).json({ 
          error: 'Keine Berechtigung',
          details: 'Administrator-Rechte erforderlich'
        });
      }

      req.userPermissions = userPermissions;
      next();
    } catch (error) {
      console.error('Admin check error:', error);
      res.status(500).json({ error: 'Fehler bei der Berechtigungsprüfung' });
    }
  };
};

/**
 * Check if user has any of the specified roles
 * @param {string[]} roles - Array of allowed roles
 * @returns {Function} Express middleware function
 */
export const requireRole = (roles) => {
  return async (req, res, next) => {
    try {
      const userId = req.user?.id;
      
      if (!userId) {
        return res.status(401).json({ error: 'Nicht authentifiziert' });
      }

      const clubId =
        req.params.clubId ??
        req.params.clubid ??
        req.params.id ??
        req.body.clubId ??
        req.body.clubid ??
        req.query.clubId ??
        req.query.clubid;

      if (!clubId) {
        return res.status(400).json({ error: 'Club-ID fehlt' });
      }

      const userPermissions = await permissionService.getUserClubPermissions(
        userId,
        parseInt(clubId)
      );

      const assignedRoleKeys = Array.isArray(userPermissions?.roles)
        ? userPermissions.roles.map((role) => role.roleKey)
        : [];
      if (!userPermissions || (!roles.includes(userPermissions.role) && !assignedRoleKeys.some((roleKey) => roles.includes(roleKey)))) {
        return res.status(403).json({ 
          error: 'Keine Berechtigung',
          details: `Erforderliche Rolle: ${roles.join(', ')}`
        });
      }

      req.userPermissions = userPermissions;
      next();
    } catch (error) {
      console.error('Role check error:', error);
      res.status(500).json({ error: 'Fehler bei der Berechtigungsprüfung' });
    }
  };
};

export default {
  authorize,
  requireOwner,
  requireAdmin,
  requireRole
};
