import { Application, Request, Response } from 'express';
import { PerformanceMonitor } from '../../utils/performance-monitor.js';

export function setupMetricsAPI(
  app: Application, 
  performanceMonitor: PerformanceMonitor,
  exportEnabled: boolean = true
): void {
  // Metrics API endpoints setup

  // System overview metrics
  app.get('/api/metrics/overview', async (req: Request, res: Response) => {
    try {
      const metrics = await performanceMonitor.getSystemMetrics();
      
      res.json({
        success: true,
        data: metrics,
        timestamp: new Date().toISOString()
      });
    } catch (error) {
      console.error('📊 Error fetching system metrics:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch system metrics',
        message: (error as Error).message
      });
    }
  });

  // Tool-specific metrics
  app.get('/api/metrics/tools', async (req: Request, res: Response) => {
    try {
      const { toolName, timeRange = '24h' } = req.query;
      
      if (toolName && typeof toolName === 'string') {
        // Get metrics for specific tool
        const metrics = await performanceMonitor.getToolMetrics(toolName);
        res.json({
          success: true,
          data: {
            toolName,
            metrics,
            timeRange
          },
          timestamp: new Date().toISOString()
        });
      } else {
        // Get metrics for all tools
        const systemMetrics = performanceMonitor.getSystemMetrics();
        
        // Build tool metrics from the available data
        const toolMetrics: Record<string, any> = {};
        
        // Extract data from top performing tools
        systemMetrics.topPerformingTools.forEach(tool => {
          toolMetrics[tool.tool] = {
            calls: tool.calls,
            successRate: tool.successRate
          };
        });
        
        // Add data from slowest tools
        systemMetrics.slowestTools.forEach(tool => {
          if (!toolMetrics[tool.tool]) {
            toolMetrics[tool.tool] = {};
          }
          toolMetrics[tool.tool].avgTime = tool.avgTime;
          toolMetrics[tool.tool].calls = tool.calls;
        });
        
        // Add data from error-prone tools
        systemMetrics.mostErrorProneTools.forEach(tool => {
          if (!toolMetrics[tool.tool]) {
            toolMetrics[tool.tool] = {};
          }
          toolMetrics[tool.tool].errorRate = tool.errorRate;
          toolMetrics[tool.tool].calls = tool.calls;
        });
        
        res.json({
          success: true,
          data: {
            tools: toolMetrics,
            systemMetrics,
            timeRange
          },
          timestamp: new Date().toISOString()
        });
      }
    } catch (error) {
      console.error('📊 Error fetching tool metrics:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch tool metrics',
        message: (error as Error).message
      });
    }
  });

  // Performance trends over time
  app.get('/api/metrics/trends', async (req: Request, res: Response) => {
    try {
      const { timeRange = '7d', metric = 'performance' } = req.query;
      
      // This would need to be implemented in PerformanceMonitor
      // For now, return sample trend data
      const trends = {
        timeRange,
        metric,
        dataPoints: [
          { timestamp: new Date(Date.now() - 6 * 24 * 60 * 60 * 1000).toISOString(), value: 95.2 },
          { timestamp: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000).toISOString(), value: 97.1 },
          { timestamp: new Date(Date.now() - 4 * 24 * 60 * 60 * 1000).toISOString(), value: 94.8 },
          { timestamp: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString(), value: 96.5 },
          { timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(), value: 98.2 },
          { timestamp: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString(), value: 97.9 },
          { timestamp: new Date().toISOString(), value: 96.8 }
        ]
      };
      
      res.json({
        success: true,
        data: trends,
        timestamp: new Date().toISOString()
      });
    } catch (error) {
      console.error('📊 Error fetching performance trends:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch performance trends',
        message: (error as Error).message
      });
    }
  });

  // Quality metrics
  app.get('/api/metrics/quality', async (req: Request, res: Response) => {
    try {
      const { toolName, timeRange = '7d' } = req.query;
      
      const qualityMetrics = await performanceMonitor.getQualityMetrics(
        typeof toolName === 'string' ? toolName : undefined
      );
      
      res.json({
        success: true,
        data: {
          toolName: toolName || 'all',
          timeRange,
          qualityMetrics
        },
        timestamp: new Date().toISOString()
      });
    } catch (error) {
      console.error('📊 Error fetching quality metrics:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch quality metrics',
        message: (error as Error).message
      });
    }
  });

  // Performance alerts
  app.get('/api/metrics/alerts', async (req: Request, res: Response) => {
    try {
      const alerts = await performanceMonitor.generateAlerts();
      
      res.json({
        success: true,
        data: {
          alerts,
          count: alerts.length
        },
        timestamp: new Date().toISOString()
      });
    } catch (error) {
      console.error('📊 Error fetching performance alerts:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch performance alerts',
        message: (error as Error).message
      });
    }
  });

  // Record quality evaluation
  app.post('/api/metrics/quality/evaluate', async (req: Request, res: Response) => {
    try {
      const { toolName, quality, feedback, executionId } = req.body;
      
      if (!toolName || quality === undefined) {
        return res.status(400).json({
          success: false,
          error: 'Missing required fields: toolName and quality are required'
        });
      }

      if (quality < 1 || quality > 10) {
        return res.status(400).json({
          success: false,
          error: 'Quality rating must be between 1 and 10'
        });
      }

      performanceMonitor.recordQualityEvaluation({
        toolName,
        outputQuality: quality,
        appropriatenessScore: quality,
        completenessScore: quality,
        accuracyScore: quality,
        comments: feedback,
        evaluationCriteria: ['user_feedback']
      });
      
      res.json({
        success: true,
        message: 'Quality evaluation recorded successfully',
        data: {
          toolName,
          quality,
          feedback
        },
        timestamp: new Date().toISOString()
      });
    } catch (error) {
      console.error('📊 Error recording quality evaluation:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to record quality evaluation',
        message: (error as Error).message
      });
    }
  });

  // Export metrics data
  if (exportEnabled) {
    app.get('/api/metrics/export', async (req: Request, res: Response) => {
      try {
        const { format = 'csv', timeRange = '24h', includeQuality = 'true' } = req.query;
        
        const exportData = await performanceMonitor.exportMetrics(format as 'json' | 'csv');
        const exportPath = `.atlas/exports/metrics-${new Date().toISOString().split('T')[0]}.${format}`;
        
        // Save to file
        const fs = await import('fs/promises');
        const path = await import('path');
        await fs.mkdir(path.dirname(exportPath), { recursive: true });
        await fs.writeFile(exportPath, typeof exportData === 'string' ? exportData : JSON.stringify(exportData));
        
        res.json({
          success: true,
          data: {
            exportPath,
            format,
            timeRange,
            includeQuality: includeQuality === 'true'
          },
          message: 'Metrics exported successfully',
          timestamp: new Date().toISOString()
        });
      } catch (error) {
        console.error('📊 Error exporting metrics:', error);
        res.status(500).json({
          success: false,
          error: 'Failed to export metrics',
          message: (error as Error).message
        });
      }
    });

    app.get('/api/metrics/download/:filename', async (req: Request, res: Response) => {
      try {
        const { filename } = req.params;
        
        // Basic security check
        if (!filename.match(/^[a-zA-Z0-9_-]+\.(csv|json)$/)) {
          return res.status(400).json({
            success: false,
            error: 'Invalid filename format'
          });
        }
        
        // This would need to serve files from the export directory
        // For now, return a placeholder response
        res.json({
          success: false,
          error: 'File download not implemented yet',
          message: 'Use the export endpoint to generate files'
        });
      } catch (error) {
        console.error('📊 Error downloading metrics file:', error);
        res.status(500).json({
          success: false,
          error: 'Failed to download metrics file',
          message: (error as Error).message
        });
      }
    });
  }

  // Record tool execution
  app.post('/api/metrics/record', async (req: Request, res: Response) => {
    try {
      const { tool, success, duration, metadata } = req.body;
      
      if (!tool || success === undefined) {
        return res.status(400).json({
          success: false,
          error: 'Tool name and success status are required'
        });
      }
      
      performanceMonitor.recordToolExecution(tool, duration || 0, success);
      
      res.json({
        success: true,
        message: 'Tool execution recorded',
        data: { tool, success, duration },
        timestamp: new Date().toISOString()
      });
    } catch (error) {
      console.error('📊 Error recording tool execution:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to record tool execution',
        message: (error as Error).message
      });
    }
  });

  // Get module-specific metrics
  app.get('/api/metrics/modules', async (req: Request, res: Response) => {
    try {
      const { moduleName } = req.query;
      
      const moduleMetrics = await performanceMonitor.getModuleMetrics(
        typeof moduleName === 'string' ? moduleName : undefined
      );
      
      res.json({
        success: true,
        data: moduleMetrics,
        timestamp: new Date().toISOString()
      });
    } catch (error) {
      console.error('📊 Error fetching module metrics:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to fetch module metrics',
        message: (error as Error).message
      });
    }
  });

  // Analyze performance bottlenecks
  app.get('/api/metrics/bottlenecks', async (req: Request, res: Response) => {
    try {
      const options = {
        threshold: Number(req.query.threshold) || 500
      };
      
      const bottlenecks = await performanceMonitor.analyzeBottlenecks(options);
      
      res.json({
        success: true,
        data: bottlenecks,
        timestamp: new Date().toISOString()
      });
    } catch (error) {
      console.error('📊 Error analyzing bottlenecks:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to analyze bottlenecks',
        message: (error as Error).message
      });
    }
  });

  // Generate performance report
  app.get('/api/metrics/report', async (req: Request, res: Response) => {
    try {
      const options = {
        format: req.query.format as string || 'json',
        includeRecommendations: req.query.includeRecommendations === 'true'
      };
      
      const report = await performanceMonitor.generatePerformanceReport(options);
      
      res.json({
        success: true,
        data: report,
        timestamp: new Date().toISOString()
      });
    } catch (error) {
      console.error('📊 Error generating performance report:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to generate performance report',
        message: (error as Error).message
      });
    }
  });

  // Clear metrics
  app.delete('/api/metrics/clear', async (req: Request, res: Response) => {
    try {
      const { confirm, before } = req.query;
      
      if (confirm !== 'yes') {
        return res.status(400).json({
          success: false,
          error: 'Confirmation required to clear metrics'
        });
      }
      
      const options = before ? { before: before as string } : undefined;
      await performanceMonitor.clearMetrics(options);
      
      res.json({
        success: true,
        message: 'Metrics cleared successfully',
        timestamp: new Date().toISOString()
      });
    } catch (error) {
      console.error('📊 Error clearing metrics:', error);
      res.status(500).json({
        success: false,
        error: 'Failed to clear metrics',
        message: (error as Error).message
      });
    }
  });

  // Health check for metrics service
  app.get('/api/metrics/health', async (req: Request, res: Response) => {
    try {
      // Test if performance monitor is working
      const testMetrics = await performanceMonitor.getSystemMetrics();
      
      res.json({
        success: true,
        status: 'healthy',
        data: {
          metricsCollected: testMetrics ? true : false,
          exportEnabled,
          features: {
            systemMetrics: true,
            toolMetrics: true,
            qualityMetrics: true,
            alerts: true,
            export: exportEnabled
          }
        },
        timestamp: new Date().toISOString()
      });
    } catch (error) {
      console.error('📊 Metrics health check failed:', error);
      res.status(503).json({
        success: false,
        status: 'unhealthy',
        error: 'Metrics service is not functioning properly',
        message: (error as Error).message,
        timestamp: new Date().toISOString()
      });
    }
  });
}