import { MonitoringConfig, MonitoringStatus, Alert, AlertStatus } from '../../types/monitoring';
import { logger } from '../../utils/logger';
import { v4 as uuidv4 } from 'uuid';

export class MonitoringAlertService {
  private static monitoringConfigs: Map<string, MonitoringConfig> = new Map();
  private static monitoringStatus: Map<string, MonitoringStatus> = new Map();
  private static alerts: Map<string, Alert> = new Map();

  static async configureMonitoring(config: MonitoringConfig): Promise<{ success: boolean; message: string }> {
    try {
      this.monitoringConfigs.set(config.id, config);
      this.monitoringStatus.set(config.id, {
        id: uuidv4(),
        configId: config.id,
        status: 'healthy',
        lastCheck: new Date(),
        value: 0
      });

      logger.info(`Monitoring config ${config.id} configured successfully`);
      return { success: true, message: 'Monitoring config configured successfully' };
    } catch (error) {
      logger.error(`Error configuring monitoring: ${error}`);
      return { success: false, message: `Error configuring monitoring: ${error}` };
    }
  }

  static async triggerAlert(configId: string, severity: 'low' | 'medium' | 'high' | 'critical', message: string): Promise<{ success: boolean; alertId: string; message: string }> {
    try {
      const config = this.monitoringConfigs.get(configId);
      if (!config) {
        return { success: false, alertId: '', message: 'Monitoring config not found' };
      }

      const alertId = uuidv4();
      const alert: Alert = {
        id: alertId,
        type: config.type,
        severity,
        message,
        status: 'active',
        createdAt: new Date()
      };

      this.alerts.set(alertId, alert);

      const status = this.monitoringStatus.get(configId);
      if (status) {
        status.lastCheck = new Date();
        status.value = severity === 'critical' ? 100 : severity === 'high' ? 75 : severity === 'medium' ? 50 : 25;
        status.status = severity === 'critical' ? 'critical' : severity === 'high' ? 'warning' : 'healthy';
        this.monitoringStatus.set(configId, status);
      }

      logger.info(`Alert ${alertId} triggered for ${configId} with severity ${severity}`);
      return { success: true, alertId, message: 'Alert triggered successfully' };
    } catch (error) {
      logger.error(`Error triggering alert: ${error}`);
      return { success: false, alertId: '', message: `Error triggering alert: ${error}` };
    }
  }

  static async resolveAlert(alertId: string): Promise<{ success: boolean; message: string }> {
    try {
      const alert = this.alerts.get(alertId);
      if (!alert) {
        return { success: false, message: 'Alert not found' };
      }

      alert.status = 'resolved';
      alert.resolvedAt = new Date();
      this.alerts.set(alertId, alert);

      logger.info(`Alert ${alertId} resolved`);
      return { success: true, message: 'Alert resolved successfully' };
    } catch (error) {
      logger.error(`Error resolving alert: ${error}`);
      return { success: false, message: `Error resolving alert: ${error}` };
    }
  }

  static async getMonitoringStatus(configId: string): Promise<MonitoringStatus | null> {
    const status = this.monitoringStatus.get(configId);
    if (!status) {
      return {
        id: 'unknown',
        configId,
        status: 'healthy',
        lastCheck: new Date(),
        value: 0
      };
    }
    return status;
  }

  static async listAlerts(status?: AlertStatus): Promise<Alert[]> {
    const alerts: Alert[] = [];

    for (const alert of this.alerts.values()) {
      if (!status || alert.status === status) {
        alerts.push(alert);
      }
    }

    alerts.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());

    return alerts;
  }

  static async listMonitoringConfigs(): Promise<Array<{ id: string; config: MonitoringConfig; status: MonitoringStatus }>> {
    const configs: Array<{ id: string; config: MonitoringConfig; status: MonitoringStatus }> = [];

    for (const [id, config] of this.monitoringConfigs.entries()) {
      const status = this.monitoringStatus.get(id) || {
        id: 'unknown',
        configId: id,
        status: 'healthy' as const,
        lastCheck: new Date(),
        value: 0
      };
      configs.push({ id, config, status });
    }

    return configs;
  }
}
