/**
 * Security Configuration API Routes
 * Manage thresholds, risk signatures, and response protocols
 * Admin-only endpoints for security configuration
 */

const express = require('express');
const router = express.Router();
const { authenticate } = require('../middleware/auth');
const { requirePermission } = require('../middleware/rbac');
const logger = require('../utils/logger');
const thresholdManager = require('../utils/thresholdManager');
const riskSignatureManager = require('../utils/riskSignatureManager');
const responseProtocolManager = require('../utils/responseProtocolManager');

// Validation middleware
const validatePagination = (req, res, next) => {
  const limit = parseInt(req.query.limit) || 100;
  req.query.limit = Math.min(Math.max(limit, 1), 1000);
  next();
};

const validateIdParam = (req, res, next) => {
  if (!req.params.id || typeof req.params.id !== 'string') {
    return res.status(400).json({
      success: false,
      message: 'Invalid ID parameter'
    });
  }
  next();
};

// ===========================
// THRESHOLD MANAGEMENT ROUTES
// ===========================

/**
 * GET /api/security-config/thresholds
 * Get all configured thresholds
 */
router.get('/thresholds',
  authenticate,
  requirePermission('security.manage'),
  validatePagination,
  async (req, res) => {
    try {
      const filters = {
        patternType: req.query.pattern_type,
        enabled: req.query.enabled !== undefined ? req.query.enabled === 'true' : undefined,
        limit: req.query.limit
      };

      const thresholds = await thresholdManager.getThresholds(filters);
      const stats = await thresholdManager.getStatistics();

      res.json({
        success: true,
        data: thresholds,
        statistics: stats,
        count: thresholds.length
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error getting thresholds:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to get thresholds',
        error: error.message
      });
    }
  }
);

/**
 * GET /api/security-config/thresholds/:id
 * Get threshold by ID
 */
router.get('/thresholds/:id',
  authenticate,
  requirePermission('security.manage'),
  validateIdParam,
  async (req, res) => {
    try {
      const threshold = await thresholdManager.getThresholdById(req.params.id);

      if (!threshold) {
        return res.status(404).json({
          success: false,
          message: 'Threshold not found'
        });
      }

      res.json({
        success: true,
        data: threshold
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error getting threshold:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to get threshold',
        error: error.message
      });
    }
  }
);

/**
 * POST /api/security-config/thresholds
 * Create new threshold
 */
router.post('/thresholds',
  authenticate,
  requirePermission('security.manage'),
  async (req, res) => {
    try {
      const { name, description, pattern_type, metric_name, operator, threshold_value, time_window_minutes, severity, enabled } = req.body;

      // Validation
      if (!name || !pattern_type || !metric_name || !operator || threshold_value === undefined || !severity) {
        return res.status(400).json({
          success: false,
          message: 'Missing required fields: name, pattern_type, metric_name, operator, threshold_value, severity'
        });
      }

      const validOperators = ['>=', '>', '<=', '<', '==', '!='];
      if (!validOperators.includes(operator)) {
        return res.status(400).json({
          success: false,
          message: 'Invalid operator. Must be one of: ' + validOperators.join(', ')
        });
      }

      const validSeverities = ['low', 'medium', 'high', 'critical'];
      if (!validSeverities.includes(severity)) {
        return res.status(400).json({
          success: false,
          message: 'Invalid severity. Must be one of: ' + validSeverities.join(', ')
        });
      }

      const result = await thresholdManager.createThreshold({
        name,
        description,
        pattern_type,
        metric_name,
        operator,
        threshold_value: parseInt(threshold_value),
        time_window_minutes: time_window_minutes ? parseInt(time_window_minutes) : 30,
        severity,
        enabled
      }, req.user.id);

      res.status(201).json({
        success: true,
        message: 'Threshold created successfully',
        data: result
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error creating threshold:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to create threshold',
        error: error.message
      });
    }
  }
);

/**
 * PUT /api/security-config/thresholds/:id
 * Update threshold
 */
router.put('/thresholds/:id',
  authenticate,
  requirePermission('security.manage'),
  validateIdParam,
  async (req, res) => {
    try {
      const updates = {};
      const allowedFields = ['name', 'description', 'operator', 'threshold_value', 'time_window_minutes', 'severity', 'enabled'];

      for (const field of allowedFields) {
        if (req.body[field] !== undefined) {
          updates[field] = req.body[field];
        }
      }

      if (Object.keys(updates).length === 0) {
        return res.status(400).json({
          success: false,
          message: 'No valid fields to update'
        });
      }

      await thresholdManager.updateThreshold(req.params.id, updates, req.user.id);

      res.json({
        success: true,
        message: 'Threshold updated successfully'
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error updating threshold:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to update threshold',
        error: error.message
      });
    }
  }
);

/**
 * DELETE /api/security-config/thresholds/:id
 * Delete threshold
 */
router.delete('/thresholds/:id',
  authenticate,
  requirePermission('security.manage'),
  validateIdParam,
  async (req, res) => {
    try {
      await thresholdManager.deleteThreshold(req.params.id, req.user.id);

      res.json({
        success: true,
        message: 'Threshold deleted successfully'
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error deleting threshold:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to delete threshold',
        error: error.message
      });
    }
  }
);

// ===========================
// RISK SIGNATURE ROUTES
// ===========================

/**
 * GET /api/security-config/signatures
 * Get all risk signatures
 */
router.get('/signatures',
  authenticate,
  requirePermission('security.manage'),
  validatePagination,
  async (req, res) => {
    try {
      const filters = {
        signatureType: req.query.signature_type,
        threatLevel: req.query.threat_level,
        enabled: req.query.enabled !== undefined ? req.query.enabled === 'true' : undefined,
        limit: req.query.limit
      };

      const signatures = await riskSignatureManager.getSignatures(filters);
      const stats = await riskSignatureManager.getStatistics();

      res.json({
        success: true,
        data: signatures,
        statistics: stats,
        count: signatures.length
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error getting signatures:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to get signatures',
        error: error.message
      });
    }
  }
);

/**
 * GET /api/security-config/signatures/:id
 * Get signature by ID
 */
router.get('/signatures/:id',
  authenticate,
  requirePermission('security.manage'),
  validateIdParam,
  async (req, res) => {
    try {
      const signature = await riskSignatureManager.getSignatureById(req.params.id);

      if (!signature) {
        return res.status(404).json({
          success: false,
          message: 'Signature not found'
        });
      }

      res.json({
        success: true,
        data: signature
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error getting signature:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to get signature',
        error: error.message
      });
    }
  }
);

/**
 * POST /api/security-config/signatures
 * Create new risk signature
 */
router.post('/signatures',
  authenticate,
  requirePermission('security.manage'),
  async (req, res) => {
    try {
      const { name, description, signature_type, pattern, match_type, threat_level, confidence, enabled, auto_block } = req.body;

      // Validation
      if (!name || !signature_type || !pattern || !match_type || !threat_level) {
        return res.status(400).json({
          success: false,
          message: 'Missing required fields: name, signature_type, pattern, match_type, threat_level'
        });
      }

      const validMatchTypes = ['regex', 'regex_case_insensitive', 'exact', 'contains', 'custom'];
      if (!validMatchTypes.includes(match_type)) {
        return res.status(400).json({
          success: false,
          message: 'Invalid match_type. Must be one of: ' + validMatchTypes.join(', ')
        });
      }

      const validThreatLevels = ['low', 'medium', 'high', 'critical'];
      if (!validThreatLevels.includes(threat_level)) {
        return res.status(400).json({
          success: false,
          message: 'Invalid threat_level. Must be one of: ' + validThreatLevels.join(', ')
        });
      }

      const result = await riskSignatureManager.createSignature({
        name,
        description,
        signature_type,
        pattern,
        match_type,
        threat_level,
        confidence: confidence !== undefined ? parseFloat(confidence) : 0.8,
        enabled,
        auto_block
      }, req.user.id);

      res.status(201).json({
        success: true,
        message: 'Signature created successfully',
        data: result
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error creating signature:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to create signature',
        error: error.message
      });
    }
  }
);

/**
 * PUT /api/security-config/signatures/:id
 * Update risk signature
 */
router.put('/signatures/:id',
  authenticate,
  requirePermission('security.manage'),
  validateIdParam,
  async (req, res) => {
    try {
      const updates = {};
      const allowedFields = ['name', 'description', 'pattern', 'match_type', 'threat_level', 'confidence', 'enabled', 'auto_block'];

      for (const field of allowedFields) {
        if (req.body[field] !== undefined) {
          updates[field] = req.body[field];
        }
      }

      if (Object.keys(updates).length === 0) {
        return res.status(400).json({
          success: false,
          message: 'No valid fields to update'
        });
      }

      await riskSignatureManager.updateSignature(req.params.id, updates, req.user.id);

      res.json({
        success: true,
        message: 'Signature updated successfully'
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error updating signature:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to update signature',
        error: error.message
      });
    }
  }
);

/**
 * DELETE /api/security-config/signatures/:id
 * Delete risk signature
 */
router.delete('/signatures/:id',
  authenticate,
  requirePermission('security.manage'),
  validateIdParam,
  async (req, res) => {
    try {
      await riskSignatureManager.deleteSignature(req.params.id, req.user.id);

      res.json({
        success: true,
        message: 'Signature deleted successfully'
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error deleting signature:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to delete signature',
        error: error.message
      });
    }
  }
);

// ===========================
// RESPONSE PROTOCOL ROUTES
// ===========================

/**
 * GET /api/security-config/protocols
 * Get all response protocols
 */
router.get('/protocols',
  authenticate,
  requirePermission('security.manage'),
  validatePagination,
  async (req, res) => {
    try {
      const filters = {
        triggerType: req.query.trigger_type,
        severity: req.query.severity,
        enabled: req.query.enabled !== undefined ? req.query.enabled === 'true' : undefined,
        limit: req.query.limit
      };

      const protocols = await responseProtocolManager.getProtocols(filters);
      const stats = await responseProtocolManager.getStatistics();

      res.json({
        success: true,
        data: protocols,
        statistics: stats,
        count: protocols.length
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error getting protocols:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to get protocols',
        error: error.message
      });
    }
  }
);

/**
 * GET /api/security-config/protocols/:id
 * Get protocol by ID
 */
router.get('/protocols/:id',
  authenticate,
  requirePermission('security.manage'),
  validateIdParam,
  async (req, res) => {
    try {
      const protocol = await responseProtocolManager.getProtocolById(req.params.id);

      if (!protocol) {
        return res.status(404).json({
          success: false,
          message: 'Protocol not found'
        });
      }

      res.json({
        success: true,
        data: protocol
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error getting protocol:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to get protocol',
        error: error.message
      });
    }
  }
);

/**
 * POST /api/security-config/protocols
 * Create new response protocol
 */
router.post('/protocols',
  authenticate,
  requirePermission('security.manage'),
  async (req, res) => {
    try {
      const { name, description, trigger_type, trigger_condition, actions, severity, enabled, auto_execute, cooldown_minutes } = req.body;

      // Validation
      if (!name || !trigger_type || !trigger_condition || !actions || !severity) {
        return res.status(400).json({
          success: false,
          message: 'Missing required fields: name, trigger_type, trigger_condition, actions, severity'
        });
      }

      const validTriggerTypes = ['anomaly', 'threshold', 'signature'];
      if (!validTriggerTypes.includes(trigger_type)) {
        return res.status(400).json({
          success: false,
          message: 'Invalid trigger_type. Must be one of: ' + validTriggerTypes.join(', ')
        });
      }

      const validSeverities = ['low', 'medium', 'high', 'critical'];
      if (!validSeverities.includes(severity)) {
        return res.status(400).json({
          success: false,
          message: 'Invalid severity. Must be one of: ' + validSeverities.join(', ')
        });
      }

      if (!Array.isArray(actions) || actions.length === 0) {
        return res.status(400).json({
          success: false,
          message: 'actions must be a non-empty array'
        });
      }

      const result = await responseProtocolManager.createProtocol({
        name,
        description,
        trigger_type,
        trigger_condition,
        actions,
        severity,
        enabled,
        auto_execute,
        cooldown_minutes: cooldown_minutes ? parseInt(cooldown_minutes) : 60
      }, req.user.id);

      res.status(201).json({
        success: true,
        message: 'Protocol created successfully',
        data: result
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error creating protocol:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to create protocol',
        error: error.message
      });
    }
  }
);

/**
 * PUT /api/security-config/protocols/:id
 * Update response protocol
 */
router.put('/protocols/:id',
  authenticate,
  requirePermission('security.manage'),
  validateIdParam,
  async (req, res) => {
    try {
      const updates = {};
      const allowedFields = ['name', 'description', 'trigger_condition', 'actions', 'severity', 'enabled', 'auto_execute', 'cooldown_minutes'];

      for (const field of allowedFields) {
        if (req.body[field] !== undefined) {
          updates[field] = req.body[field];
        }
      }

      if (Object.keys(updates).length === 0) {
        return res.status(400).json({
          success: false,
          message: 'No valid fields to update'
        });
      }

      await responseProtocolManager.updateProtocol(req.params.id, updates, req.user.id);

      res.json({
        success: true,
        message: 'Protocol updated successfully'
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error updating protocol:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to update protocol',
        error: error.message
      });
    }
  }
);

/**
 * DELETE /api/security-config/protocols/:id
 * Delete response protocol
 */
router.delete('/protocols/:id',
  authenticate,
  requirePermission('security.manage'),
  validateIdParam,
  async (req, res) => {
    try {
      await responseProtocolManager.deleteProtocol(req.params.id, req.user.id);

      res.json({
        success: true,
        message: 'Protocol deleted successfully'
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error deleting protocol:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to delete protocol',
        error: error.message
      });
    }
  }
);

/**
 * GET /api/security-config/protocols/:id/history
 * Get execution history for protocol
 */
router.get('/protocols/:id/history',
  authenticate,
  requirePermission('security.manage'),
  validateIdParam,
  validatePagination,
  async (req, res) => {
    try {
      const history = await responseProtocolManager.getExecutionHistory({
        protocolId: req.params.id,
        limit: req.query.limit
      });

      res.json({
        success: true,
        data: history,
        count: history.length
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error getting protocol history:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to get protocol history',
        error: error.message
      });
    }
  }
);

// ===========================
// DASHBOARD/OVERVIEW ROUTES
// ===========================

/**
 * GET /api/security-config/dashboard
 * Get security configuration dashboard overview
 */
router.get('/dashboard',
  authenticate,
  requirePermission('security.manage'),
  async (req, res) => {
    try {
      const [thresholdStats, signatureStats, protocolStats] = await Promise.all([
        thresholdManager.getStatistics(),
        riskSignatureManager.getStatistics(),
        responseProtocolManager.getStatistics()
      ]);

      res.json({
        success: true,
        data: {
          thresholds: thresholdStats,
          signatures: signatureStats,
          protocols: protocolStats
        }
      });
    } catch (error) {
      logger.error('[SecurityConfig API] Error getting dashboard:', error);
      res.status(500).json({
        success: false,
        message: 'Failed to get dashboard data',
        error: error.message
      });
    }
  }
);

module.exports = router;
