/**
 * Alert Notification Service
 * Handles sending alerts to Slack, PagerDuty, and email
 */

import { alertConfigService } from './alertConfigService.ts';

export interface AlertNotification {
  type: string;
  severity: 'low' | 'medium' | 'high' | 'critical';
  title: string;
  message: string;
  details?: Record<string, any>;
  timestamp: Date;
}

class AlertNotificationService {
  private notificationHistory: AlertNotification[] = [];
  private maxHistorySize = 1000;

  /**
   * Send alert through configured channels
   */
  async sendAlert(notification: Omit<AlertNotification, 'timestamp'>) {
    if (!alertConfigService.isEnabled()) {
      console.log('[Alert Notification] Alerting disabled, skipping notification');
      return;
    }

    const fullNotification: AlertNotification = {
      ...notification,
      timestamp: new Date(),
    };

    // Record in history
    this.recordNotification(fullNotification);

    // Get configured channels
    const channels = alertConfigService.getNotificationChannels(notification.type);

    console.log(`[Alert Notification] Sending ${notification.severity} alert to channels:`, channels);

    // Send to each channel
    const results = await Promise.allSettled([
      channels.includes('slack') ? this.sendToSlack(fullNotification) : Promise.resolve(),
      channels.includes('pagerduty') ? this.sendToPagerDuty(fullNotification) : Promise.resolve(),
      channels.includes('email') ? this.sendEmail(fullNotification) : Promise.resolve(),
    ]);

    // Log results
    results.forEach((result, idx) => {
      const channelName = channels[idx];
      if (result.status === 'rejected') {
        console.error(`[Alert Notification] Failed to send to ${channelName}:`, result.reason);
      }
    });
  }

  /**
   * Send alert to Slack
   */
  private async sendToSlack(notification: AlertNotification): Promise<void> {
    const webhook = alertConfigService.getAllConfig().slackWebhook;
    if (!webhook) {
      throw new Error('Slack webhook not configured');
    }

    const color = {
      low: '#36a64f',
      medium: '#ff9900',
      high: '#ff6600',
      critical: '#ff0000',
    }[notification.severity];

    const payload = {
      attachments: [
        {
          color,
          title: notification.title,
          text: notification.message,
          fields: [
            {
              title: 'Severity',
              value: notification.severity.toUpperCase(),
              short: true,
            },
            {
              title: 'Type',
              value: notification.type,
              short: true,
            },
            {
              title: 'Timestamp',
              value: notification.timestamp.toISOString(),
              short: false,
            },
          ],
          footer: 'CoinKrazy Monitoring',
          ts: Math.floor(notification.timestamp.getTime() / 1000),
        },
      ],
    };

    if (notification.details) {
      payload.attachments[0].fields.push({
        title: 'Details',
        value: JSON.stringify(notification.details, null, 2),
        short: false,
      });
    }

    try {
      const response = await fetch(webhook, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });

      if (!response.ok) {
        throw new Error(`Slack API error: ${response.statusText}`);
      }

      console.log('[Alert Notification] Slack notification sent successfully');
    } catch (error) {
      console.error('[Alert Notification] Failed to send Slack notification:', error);
      throw error;
    }
  }

  /**
   * Send alert to PagerDuty
   */
  private async sendToPagerDuty(notification: AlertNotification): Promise<void> {
    const integrationKey = alertConfigService.getAllConfig().pagerdutyKey;
    if (!integrationKey) {
      throw new Error('PagerDuty integration key not configured');
    }

    const severity = {
      low: 'info',
      medium: 'warning',
      high: 'error',
      critical: 'critical',
    }[notification.severity];

    const payload = {
      routing_key: integrationKey,
      event_action: 'trigger',
      dedup_key: `${notification.type}-${Math.floor(notification.timestamp.getTime() / 60000)}`, // Group by minute
      payload: {
        summary: notification.title,
        severity,
        source: 'CoinKrazy Monitoring',
        custom_details: {
          message: notification.message,
          type: notification.type,
          details: notification.details,
        },
        timestamp: notification.timestamp.toISOString(),
      },
    };

    try {
      const response = await fetch('https://events.pagerduty.com/v2/enqueue', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });

      if (!response.ok) {
        throw new Error(`PagerDuty API error: ${response.statusText}`);
      }

      console.log('[Alert Notification] PagerDuty notification sent successfully');
    } catch (error) {
      console.error('[Alert Notification] Failed to send PagerDuty notification:', error);
      throw error;
    }
  }

  /**
   * Send alert via email
   */
  private async sendEmail(notification: AlertNotification): Promise<void> {
    const recipients = alertConfigService.getAllConfig().emailRecipients;
    if (!recipients || recipients.length === 0) {
      throw new Error('Email recipients not configured');
    }

    const subject = `[${notification.severity.toUpperCase()}] ${notification.title}`;
    const htmlContent = `
      <html>
        <body style="font-family: Arial, sans-serif;">
          <h2 style="color: #333;">${notification.title}</h2>
          <p><strong>Severity:</strong> <span style="color: ${this.getSeverityColor(notification.severity)};">${notification.severity.toUpperCase()}</span></p>
          <p><strong>Type:</strong> ${notification.type}</p>
          <p><strong>Message:</strong></p>
          <p>${notification.message}</p>
          ${notification.details ? `<p><strong>Details:</strong></p><pre>${JSON.stringify(notification.details, null, 2)}</pre>` : ''}
          <p><strong>Timestamp:</strong> ${notification.timestamp.toISOString()}</p>
          <hr>
          <p><small>CoinKrazy Monitoring System</small></p>
        </body>
      </html>
    `;

    // In production, this would use Brevo or another email service
    console.log('[Alert Notification] Email alert would be sent to:', recipients);
    console.log('[Alert Notification] Subject:', subject);
    console.log('[Alert Notification] Content:', htmlContent);

    // For now, just log the email
    // In production, integrate with Brevo email service
  }

  /**
   * Record notification in history
   */
  private recordNotification(notification: AlertNotification) {
    this.notificationHistory.push(notification);

    // Keep only recent notifications
    if (this.notificationHistory.length > this.maxHistorySize) {
      this.notificationHistory = this.notificationHistory.slice(-this.maxHistorySize);
    }
  }

  /**
   * Get notification history
   */
  getHistory(limit: number = 100): AlertNotification[] {
    return this.notificationHistory.slice(-limit);
  }

  /**
   * Get notifications by severity
   */
  getNotificationsBySeverity(severity: string, limit: number = 50): AlertNotification[] {
    return this.notificationHistory.filter((n) => n.severity === severity).slice(-limit);
  }

  /**
   * Get notifications by type
   */
  getNotificationsByType(type: string, limit: number = 50): AlertNotification[] {
    return this.notificationHistory.filter((n) => n.type === type).slice(-limit);
  }

  /**
   * Get recent critical alerts
   */
  getRecentCriticalAlerts(hours: number = 24): AlertNotification[] {
    const cutoffTime = new Date(Date.now() - hours * 60 * 60 * 1000);
    return this.notificationHistory.filter((n) => n.severity === 'critical' && n.timestamp >= cutoffTime);
  }

  /**
   * Clear notification history
   */
  clearHistory() {
    this.notificationHistory = [];
    console.log('[Alert Notification] History cleared');
  }

  /**
   * Get severity color for display
   */
  private getSeverityColor(severity: string): string {
    const colors = {
      low: '#36a64f',
      medium: '#ff9900',
      high: '#ff6600',
      critical: '#ff0000',
    };
    return colors[severity as keyof typeof colors] || '#999999';
  }
}

export const alertNotificationService = new AlertNotificationService();
