const permissionService = require('../services/permissionService');

/**
 * Middleware to check if user has a specific permission
 * @param {string|Array<string>} permissionCodes - Permission code(s) to check
 * @param {Object} options - Options
 * @param {boolean} options.requireAll - If true, require all permissions; if false, require any (default: false)
 * @param {boolean} options.logAudit - Whether to log to audit trail (default: true)
 * @returns {Function} Express middleware
 */
const requirePermission = (permissionCodes, options = {}) => {
  const { requireAll = false, logAudit = true } = options;
  const codes = Array.isArray(permissionCodes) ? permissionCodes : [permissionCodes];

  return async (req, res, next) => {
    try {
      if (!req.user) {
        return res.status(401).json({
          success: false,
          message: 'Authentication required'
        });
      }

      const { userId, companyId } = req.user;

      // Super admin bypass
      if (req.user.isSuperAdmin) {
        return next();
      }

      // Check permissions
      let hasAccess = false;
      if (requireAll) {
        hasAccess = await permissionService.hasAllPermissions(userId, companyId, codes);
      } else {
        hasAccess = await permissionService.hasAnyPermission(userId, companyId, codes);
      }

      if (!hasAccess) {
        // Log denied access
        if (logAudit) {
          const ipAddress = req.ip || req.connection.remoteAddress;
          const userAgent = req.get('user-agent');
          const resourceType = req.params.resourceType || req.body.resourceType || null;
          const resourceId = req.params.id || req.body.resourceId || null;

          await permissionService.logPermissionCheck(
            userId,
            codes[0], // Log first permission code
            'DENIED',
            { resourceType, resourceId, ipAddress, userAgent }
          );
        }

        return res.status(403).json({
          success: false,
          message: 'Insufficient permissions',
          requiredPermissions: codes
        });
      }

      // Log granted access (optional, can be disabled for performance)
      if (logAudit && process.env.LOG_GRANTED_PERMISSIONS === 'true') {
        const ipAddress = req.ip || req.connection.remoteAddress;
        const userAgent = req.get('user-agent');
        const resourceType = req.params.resourceType || req.body.resourceType || null;
        const resourceId = req.params.id || req.body.resourceId || null;

        await permissionService.logPermissionCheck(
          userId,
          codes[0],
          'GRANTED',
          { resourceType, resourceId, ipAddress, userAgent }
        );
      }

      next();
    } catch (error) {
      console.error('Permission middleware error:', error);
      return res.status(500).json({
        success: false,
        message: 'Error checking permissions'
      });
    }
  };
};

/**
 * Middleware to check if user has permission for a specific operation on a resource
 * @param {string} module - Module name (e.g., SALES, PURCHASE)
 * @param {string} resource - Resource name (e.g., SALES_ORDER, PURCHASE_ORDER)
 * @param {string} operation - Operation name (e.g., CREATE, EDIT, APPROVE)
 * @returns {Function} Express middleware
 */
const requireOperation = (module, resource, operation) => {
  const permissionCode = `${module}_${resource}_${operation}`;
  return requirePermission(permissionCode);
};

/**
 * Middleware factory for common operations
 */
const permissionMiddleware = {
  // Sales operations
  requireSalesQuotationCreate: () => requireOperation('SALES', 'QUOTATION', 'CREATE'),
  requireSalesQuotationApprove: () => requireOperation('SALES', 'QUOTATION', 'APPROVE'),
  requireSalesOrderCreate: () => requireOperation('SALES', 'SALES_ORDER', 'CREATE'),
  requireSalesOrderApprove: () => requireOperation('SALES', 'SALES_ORDER', 'APPROVE'),
  
  // Purchase operations
  requirePurchaseOrderCreate: () => requireOperation('PURCHASE', 'PURCHASE_ORDER', 'CREATE'),
  requirePurchaseOrderApprove: () => requireOperation('PURCHASE', 'PURCHASE_ORDER', 'APPROVE'),
  
  // Production operations
  requireProductionOrderCreate: () => requireOperation('PRODUCTION', 'PRODUCTION_ORDER', 'CREATE'),
  requireProductionOrderApprove: () => requireOperation('PRODUCTION', 'PRODUCTION_ORDER', 'APPROVE'),
  requireProductionOrderStart: () => requireOperation('PRODUCTION', 'PRODUCTION_ORDER', 'START'),
  
  // Inventory operations
  requireGoodsReceiptCreate: () => requireOperation('INVENTORY', 'GOODS_RECEIPT', 'CREATE'),
  requireGoodsIssueCreate: () => requireOperation('INVENTORY', 'GOODS_ISSUE', 'CREATE'),
  
  // QC operations
  requireQCInspectionApprove: () => requireOperation('QC', 'QC_INSPECTION', 'APPROVE'),
  
  // Finance operations
  requirePaymentVoucherApprove: () => requireOperation('FINANCE', 'PAYMENT_VOUCHER', 'APPROVE'),
  requireJournalEntryApprove: () => requireOperation('FINANCE', 'JOURNAL_ENTRY', 'APPROVE'),
  
  // Generic
  requirePermission,
  requireOperation
};

module.exports = permissionMiddleware;

