import { Router, Request, Response } from 'express';
import { uploadMonitoringService } from '../services/uploadMonitoringService';
import { addCorrelationId } from '../middleware/validation';
import { logger } from '../utils/logger';

const router = Router();

// Apply correlation ID middleware to all monitoring routes
router.use(addCorrelationId);

/**
 * GET /api/monitoring/upload-metrics
 * Get upload metrics for a specified time period
 */
router.get('/upload-metrics', async (req: Request, res: Response): Promise<void> => {
  try {
    const hours = parseInt((req.query as any)['hours'] as string) || 24;
    
    if (hours < 1 || hours > 168) { // Max 7 days
      res.status(400).json({
        success: false,
        error: 'Invalid time period',
        message: 'Hours must be between 1 and 168 (7 days)',
        correlationId: req.correlationId || undefined,
      });
      return;
    }

    const metrics = uploadMonitoringService.getUploadMetrics(hours);
    
    logger.info('Upload metrics retrieved', {
      category: 'monitoring',
      operation: 'get_upload_metrics',
      hours,
      correlationId: req.correlationId || undefined,
    });

    res.json({
      success: true,
      data: metrics,
      correlationId: req.correlationId || undefined,
    });
  } catch (error) {
    logger.error('Failed to get upload metrics', {
      category: 'monitoring',
      operation: 'get_upload_metrics',
      error: error instanceof Error ? error.message : 'Unknown error',
      correlationId: req.correlationId || undefined,
    });

    res.status(500).json({
      success: false,
      error: 'Failed to retrieve upload metrics',
      correlationId: req.correlationId || undefined,
    });
  }
});

/**
 * GET /api/monitoring/upload-health
 * Get upload pipeline health status
 */
router.get('/upload-health', async (req: Request, res: Response): Promise<void> => {
  try {
    const healthStatus = uploadMonitoringService.getUploadHealthStatus();
    
    logger.info('Upload health status retrieved', {
      category: 'monitoring',
      operation: 'get_upload_health',
      status: healthStatus.status,
      successRate: healthStatus.successRate,
      correlationId: req.correlationId || undefined,
    });

    res.json({
      success: true,
      data: healthStatus,
      correlationId: req.correlationId || undefined,
    });
  } catch (error) {
    logger.error('Failed to get upload health status', {
      category: 'monitoring',
      operation: 'get_upload_health',
      error: error instanceof Error ? error.message : 'Unknown error',
      correlationId: req.correlationId || undefined,
    });

    res.status(500).json({
      success: false,
      error: 'Failed to retrieve upload health status',
      correlationId: req.correlationId || undefined,
    });
  }
});

/**
 * GET /api/monitoring/real-time-stats
 * Get real-time upload statistics
 */
router.get('/real-time-stats', async (req: Request, res: Response): Promise<void> => {
  try {
    const stats = uploadMonitoringService.getRealTimeStats();
    
    logger.info('Real-time stats retrieved', {
      category: 'monitoring',
      operation: 'get_real_time_stats',
      activeUploads: stats.activeUploads,
      uploadsLastMinute: stats.uploadsLastMinute,
      correlationId: req.correlationId || undefined,
    });

    res.json({
      success: true,
      data: stats,
      correlationId: req.correlationId || undefined,
    });
  } catch (error) {
    logger.error('Failed to get real-time stats', {
      category: 'monitoring',
      operation: 'get_real_time_stats',
      error: error instanceof Error ? error.message : 'Unknown error',
      correlationId: req.correlationId || undefined,
    });

    res.status(500).json({
      success: false,
      error: 'Failed to retrieve real-time statistics',
      correlationId: req.correlationId || undefined,
    });
  }
});

/**
 * GET /api/monitoring/error-analysis
 * Get detailed error analysis for debugging
 */
router.get('/error-analysis', async (req: Request, res: Response): Promise<void> => {
  try {
    const hours = parseInt((req.query as any)["hours"] as string) || 24;
    
    if (hours < 1 || hours > 168) { // Max 7 days
      res.status(400).json({
        success: false,
        error: 'Invalid time period',
        message: 'Hours must be between 1 and 168 (7 days)',
        correlationId: req.correlationId || undefined,
      });
      return;
    }

    const errorAnalysis = uploadMonitoringService.getErrorAnalysis(hours);
    
    logger.info('Error analysis retrieved', {
      category: 'monitoring',
      operation: 'get_error_analysis',
      hours,
      topErrorTypesCount: errorAnalysis.topErrorTypes.length,
      topErrorStagesCount: errorAnalysis.topErrorStages.length,
      correlationId: req.correlationId || undefined,
    });

    res.json({
      success: true,
      data: errorAnalysis,
      correlationId: req.correlationId || undefined,
    });
  } catch (error) {
    logger.error('Failed to get error analysis', {
      category: 'monitoring',
      operation: 'get_error_analysis',
      error: error instanceof Error ? error.message : 'Unknown error',
      correlationId: req.correlationId || undefined,
    });

    res.status(500).json({
      success: false,
      error: 'Failed to retrieve error analysis',
      correlationId: req.correlationId || undefined,
    });
  }
});

/**
 * POST /api/monitoring/clear-old-events
 * Clear old monitoring events (admin only)
 */
router.post('/clear-old-events', async (req: Request, res: Response): Promise<void> => {
  try {
    const daysToKeep = parseInt(req.body.daysToKeep as string) || 7;
    
    if (daysToKeep < 1 || daysToKeep > 30) {
      res.status(400).json({
        success: false,
        error: 'Invalid days parameter',
        message: 'Days must be between 1 and 30',
        correlationId: req.correlationId || undefined,
      });
      return;
    }

    const removedCount = uploadMonitoringService.clearOldEvents(daysToKeep);
    
    logger.info('Old monitoring events cleared', {
      category: 'monitoring',
      operation: 'clear_old_events',
      daysToKeep,
      removedCount,
      correlationId: req.correlationId || undefined,
    });

    res.json({
      success: true,
      data: {
        removedCount,
        daysToKeep,
      },
      correlationId: req.correlationId || undefined,
    });
  } catch (error) {
    logger.error('Failed to clear old events', {
      category: 'monitoring',
      operation: 'clear_old_events',
      error: error instanceof Error ? error.message : 'Unknown error',
      correlationId: req.correlationId || undefined,
    });

    res.status(500).json({
      success: false,
      error: 'Failed to clear old monitoring events',
      correlationId: req.correlationId || undefined,
    });
  }
});

/**
 * GET /api/monitoring/dashboard
 * Get comprehensive dashboard data
 */
router.get('/dashboard', async (req: Request, res: Response): Promise<void> => {
  try {
    const hours = parseInt((req.query as any)["hours"] as string) || 24;
    
    if (hours < 1 || hours > 168) {
      res.status(400).json({
        success: false,
        error: 'Invalid time period',
        message: 'Hours must be between 1 and 168 (7 days)',
        correlationId: req.correlationId || undefined,
      });
      return;
    }

    // Get all monitoring data
    const [metrics, healthStatus, realTimeStats, errorAnalysis] = await Promise.all([
      uploadMonitoringService.getUploadMetrics(hours),
      uploadMonitoringService.getUploadHealthStatus(),
      uploadMonitoringService.getRealTimeStats(),
      uploadMonitoringService.getErrorAnalysis(hours),
    ]);

    const dashboardData = {
      metrics,
      healthStatus,
      realTimeStats,
      errorAnalysis,
      timestamp: new Date().toISOString(),
    };
    
    logger.info('Dashboard data retrieved', {
      category: 'monitoring',
      operation: 'get_dashboard',
      hours,
      correlationId: req.correlationId || undefined,
    });

    res.json({
      success: true,
      data: dashboardData,
      correlationId: req.correlationId || undefined,
    });
  } catch (error) {
    logger.error('Failed to get dashboard data', {
      category: 'monitoring',
      operation: 'get_dashboard',
      error: error instanceof Error ? error.message : 'Unknown error',
      correlationId: req.correlationId || undefined,
    });

    res.status(500).json({
      success: false,
      error: 'Failed to retrieve dashboard data',
      correlationId: req.correlationId || undefined,
    });
  }
});

export default router; 