/**
 * Monitoring routes for system health and metrics
 */

import { Hono } from 'hono';
import type { IServiceContainer } from '@stock-bot/handlers';
import { MonitoringService } from '../services/monitoring.service';

export function createMonitoringRoutes(container: IServiceContainer) {
  const monitoring = new Hono();
  const monitoringService = new MonitoringService(container);

  /**
   * Get overall system health
   */
  monitoring.get('/', async c => {
    try {
      const health = await monitoringService.getSystemHealth();

      // Set appropriate status code based on health
      const statusCode =
        health.status === 'healthy' ? 200 : health.status === 'degraded' ? 503 : 500;

      return c.json(health, statusCode);
    } catch (error) {
      return c.json(
        {
          status: 'error',
          message: 'Failed to retrieve system health',
          error: error instanceof Error ? error.message : 'Unknown error',
        },
        500
      );
    }
  });

  /**
   * Get cache/Dragonfly statistics
   */
  monitoring.get('/cache', async c => {
    try {
      const stats = await monitoringService.getCacheStats();
      return c.json(stats);
    } catch (error) {
      return c.json(
        {
          error: 'Failed to retrieve cache statistics',
          message: error instanceof Error ? error.message : 'Unknown error',
        },
        500
      );
    }
  });

  /**
   * Get queue statistics
   */
  monitoring.get('/queues', async c => {
    try {
      const stats = await monitoringService.getQueueStats();
      return c.json({ queues: stats });
    } catch (error) {
      return c.json(
        {
          error: 'Failed to retrieve queue statistics',
          message: error instanceof Error ? error.message : 'Unknown error',
        },
        500
      );
    }
  });

  /**
   * Get specific queue statistics
   */
  monitoring.get('/queues/:name', async c => {
    try {
      const queueName = c.req.param('name');
      const stats = await monitoringService.getQueueStats();
      const queueStats = stats.find(q => q.name === queueName);

      if (!queueStats) {
        return c.json(
          {
            error: 'Queue not found',
            message: `Queue '${queueName}' does not exist`,
          },
          404
        );
      }

      return c.json(queueStats);
    } catch (error) {
      return c.json(
        {
          error: 'Failed to retrieve queue statistics',
          message: error instanceof Error ? error.message : 'Unknown error',
        },
        500
      );
    }
  });

  /**
   * Get database statistics
   */
  monitoring.get('/databases', async c => {
    try {
      const stats = await monitoringService.getDatabaseStats();
      return c.json({ databases: stats });
    } catch (error) {
      return c.json(
        {
          error: 'Failed to retrieve database statistics',
          message: error instanceof Error ? error.message : 'Unknown error',
        },
        500
      );
    }
  });

  /**
   * Get specific database statistics
   */
  monitoring.get('/databases/:type', async c => {
    try {
      const dbType = c.req.param('type') as 'postgres' | 'mongodb' | 'questdb';
      const stats = await monitoringService.getDatabaseStats();
      const dbStats = stats.find(db => db.type === dbType);

      if (!dbStats) {
        return c.json(
          {
            error: 'Database not found',
            message: `Database type '${dbType}' not found or not enabled`,
          },
          404
        );
      }

      return c.json(dbStats);
    } catch (error) {
      return c.json(
        {
          error: 'Failed to retrieve database statistics',
          message: error instanceof Error ? error.message : 'Unknown error',
        },
        500
      );
    }
  });

  /**
   * Get service metrics
   */
  monitoring.get('/metrics', async c => {
    try {
      const metrics = await monitoringService.getServiceMetrics();
      return c.json(metrics);
    } catch (error) {
      return c.json(
        {
          error: 'Failed to retrieve service metrics',
          message: error instanceof Error ? error.message : 'Unknown error',
        },
        500
      );
    }
  });

  /**
   * Get detailed cache info (Redis INFO command output)
   */
  monitoring.get('/cache/info', async c => {
    try {
      if (!container.cache) {
        return c.json(
          {
            error: 'Cache not available',
            message: 'Cache service is not enabled',
          },
          503
        );
      }

      const info = await container.cache.info();
      const stats = await monitoringService.getCacheStats();

      return c.json({
        parsed: stats,
        raw: info,
      });
    } catch (error) {
      return c.json(
        {
          error: 'Failed to retrieve cache info',
          message: error instanceof Error ? error.message : 'Unknown error',
        },
        500
      );
    }
  });

  /**
   * Health check endpoint for monitoring
   */
  monitoring.get('/ping', c => {
    return c.json({
      status: 'ok',
      timestamp: new Date().toISOString(),
      service: 'monitoring',
    });
  });

  /**
   * Get service status for all microservices
   */
  monitoring.get('/services', async c => {
    try {
      const services = await monitoringService.getServiceStatus();
      return c.json({ services });
    } catch (error) {
      return c.json(
        {
          error: 'Failed to retrieve service status',
          message: error instanceof Error ? error.message : 'Unknown error',
        },
        500
      );
    }
  });

  /**
   * Get proxy statistics
   */
  monitoring.get('/proxies', async c => {
    try {
      const stats = await monitoringService.getProxyStats();
      return c.json(stats || { enabled: false });
    } catch (error) {
      return c.json(
        {
          error: 'Failed to retrieve proxy statistics',
          message: error instanceof Error ? error.message : 'Unknown error',
        },
        500
      );
    }
  });

  /**
   * Get comprehensive system overview
   */
  monitoring.get('/overview', async c => {
    try {
      const overview = await monitoringService.getSystemOverview();
      return c.json(overview);
    } catch (error) {
      return c.json(
        {
          error: 'Failed to retrieve system overview',
          message: error instanceof Error ? error.message : 'Unknown error',
        },
        500
      );
    }
  });

  /**
   * Test direct BullMQ queue access
   */
  monitoring.get('/test/queue/:name', async c => {
    const queueName = c.req.param('name');
    const { Queue } = await import('bullmq');

    const connection = {
      host: 'localhost',
      port: 6379,
      db: 0, // All queues in DB 0
    };

    const queue = new Queue(queueName, { connection });

    try {
      const counts = await queue.getJobCounts();
      await queue.close();
      return c.json({
        queueName,
        counts,
      });
    } catch (error: any) {
      await queue.close();
      return c.json(
        {
          queueName,
          error: error.message,
        },
        500
      );
    }
  });

  return monitoring;
}
