/**
 * Report Alerts System
 * Threshold-based alerts that trigger notifications when metrics exceed/fall below specified values
 */

export type AlertCondition = 'exceeds' | 'fallsBelow' | 'equals' | 'changes';
export type AlertSeverity = 'critical' | 'high' | 'medium' | 'low';
export type AlertChannel = 'email' | 'sms' | 'push' | 'in-app';

export interface ReportAlert {
  id: string;
  reportId: string;
  name: string;
  description?: string;
  metric: string;
  condition: AlertCondition;
  threshold: number;
  severity: AlertSeverity;
  channels: AlertChannel[];
  recipients: string[];
  enabled: boolean;
  createdAt: Date;
  lastTriggered?: Date;
  triggerCount: number;
  cooldownMinutes: number;
  customMessage?: string;
}

export interface AlertTrigger {
  id: string;
  alertId: string;
  reportId: string;
  metric: string;
  currentValue: number;
  threshold: number;
  condition: AlertCondition;
  triggeredAt: Date;
  severity: AlertSeverity;
  notificationsSent: number;
  acknowledged: boolean;
  acknowledgedBy?: string;
  acknowledgedAt?: Date;
}

export interface AlertStats {
  totalAlerts: number;
  enabledAlerts: number;
  disabledAlerts: number;
  totalTriggers: number;
  unacknowledgedTriggers: number;
  criticalAlerts: number;
  averageResponseTime: number;
}

/**
 * Create report alert
 */
export function createReportAlert(
  reportId: string,
  name: string,
  metric: string,
  condition: AlertCondition,
  threshold: number,
  severity: AlertSeverity,
  channels: AlertChannel[],
  recipients: string[],
  cooldownMinutes: number = 60,
  customMessage?: string
): ReportAlert {
  return {
    id: `ALERT-${Date.now()}`,
    reportId,
    name,
    metric,
    condition,
    threshold,
    severity,
    channels,
    recipients,
    enabled: true,
    createdAt: new Date(),
    triggerCount: 0,
    cooldownMinutes,
    customMessage,
  };
}

/**
 * Check if alert should trigger
 */
export function shouldTriggerAlert(alert: ReportAlert, currentValue: number): boolean {
  if (!alert.enabled) return false;

  switch (alert.condition) {
    case 'exceeds':
      return currentValue > alert.threshold;
    case 'fallsBelow':
      return currentValue < alert.threshold;
    case 'equals':
      return currentValue === alert.threshold;
    case 'changes':
      return true; // Always trigger on change
    default:
      return false;
  }
}

/**
 * Check if alert is in cooldown
 */
export function isAlertInCooldown(alert: ReportAlert): boolean {
  if (!alert.lastTriggered) return false;

  const cooldownMs = alert.cooldownMinutes * 60 * 1000;
  const timeSinceLastTrigger = Date.now() - alert.lastTriggered.getTime();

  return timeSinceLastTrigger < cooldownMs;
}

/**
 * Create alert trigger
 */
export function createAlertTrigger(
  alert: ReportAlert,
  currentValue: number
): AlertTrigger {
  return {
    id: `TRIGGER-${Date.now()}`,
    alertId: alert.id,
    reportId: alert.reportId,
    metric: alert.metric,
    currentValue,
    threshold: alert.threshold,
    condition: alert.condition,
    triggeredAt: new Date(),
    severity: alert.severity,
    notificationsSent: 0,
    acknowledged: false,
  };
}

/**
 * Get alert severity color
 */
export function getAlertSeverityColor(severity: AlertSeverity): string {
  switch (severity) {
    case 'critical':
      return '#dc2626'; // red-600
    case 'high':
      return '#ea580c'; // orange-600
    case 'medium':
      return '#eab308'; // yellow-500
    case 'low':
      return '#06b6d4'; // cyan-500
    default:
      return '#6b7280'; // gray-500
  }
}

/**
 * Get alert severity icon
 */
export function getAlertSeverityIcon(severity: AlertSeverity): string {
  switch (severity) {
    case 'critical':
      return '🚨';
    case 'high':
      return '⚠️';
    case 'medium':
      return '⚡';
    case 'low':
      return 'ℹ️';
    default:
      return '•';
  }
}

/**
 * Format alert message
 */
export function formatAlertMessage(alert: ReportAlert, trigger: AlertTrigger): string {
  const conditionText = {
    exceeds: 'exceeded',
    fallsBelow: 'fallen below',
    equals: 'equals',
    changes: 'changed',
  };

  const baseMessage = `Alert: ${alert.name} - ${alert.metric} has ${conditionText[alert.condition]} ${alert.threshold} (current: ${trigger.currentValue})`;

  if (alert.customMessage) {
    return `${baseMessage}\n\n${alert.customMessage}`;
  }

  return baseMessage;
}

/**
 * Get alerts for report
 */
export function getAlertsForReport(reportId: string, alerts: ReportAlert[]): ReportAlert[] {
  return alerts.filter(alert => alert.reportId === reportId);
}

/**
 * Get enabled alerts
 */
export function getEnabledAlerts(alerts: ReportAlert[]): ReportAlert[] {
  return alerts.filter(alert => alert.enabled);
}

/**
 * Get critical alerts
 */
export function getCriticalAlerts(alerts: ReportAlert[]): ReportAlert[] {
  return alerts.filter(alert => alert.severity === 'critical' && alert.enabled);
}

/**
 * Get alerts by severity
 */
export function getAlertsBySeverity(severity: AlertSeverity, alerts: ReportAlert[]): ReportAlert[] {
  return alerts.filter(alert => alert.severity === severity);
}

/**
 * Update alert
 */
export function updateAlert(alert: ReportAlert, updates: Partial<ReportAlert>): ReportAlert {
  return {
    ...alert,
    ...updates,
  };
}

/**
 * Enable alert
 */
export function enableAlert(alert: ReportAlert): ReportAlert {
  return updateAlert(alert, { enabled: true });
}

/**
 * Disable alert
 */
export function disableAlert(alert: ReportAlert): ReportAlert {
  return updateAlert(alert, { enabled: false });
}

/**
 * Update alert threshold
 */
export function updateAlertThreshold(alert: ReportAlert, newThreshold: number): ReportAlert {
  return updateAlert(alert, { threshold: newThreshold });
}

/**
 * Add recipient to alert
 */
export function addAlertRecipient(alert: ReportAlert, recipient: string): ReportAlert {
  if (alert.recipients.includes(recipient)) return alert;

  return updateAlert(alert, {
    recipients: [...alert.recipients, recipient],
  });
}

/**
 * Remove recipient from alert
 */
export function removeAlertRecipient(alert: ReportAlert, recipient: string): ReportAlert {
  return updateAlert(alert, {
    recipients: alert.recipients.filter(r => r !== recipient),
  });
}

/**
 * Acknowledge trigger
 */
export function acknowledgeTrigger(
  trigger: AlertTrigger,
  acknowledgedBy: string
): AlertTrigger {
  return {
    ...trigger,
    acknowledged: true,
    acknowledgedBy,
    acknowledgedAt: new Date(),
  };
}

/**
 * Get unacknowledged triggers
 */
export function getUnacknowledgedTriggers(triggers: AlertTrigger[]): AlertTrigger[] {
  return triggers.filter(trigger => !trigger.acknowledged);
}

/**
 * Get triggers for alert
 */
export function getTriggersForAlert(alertId: string, triggers: AlertTrigger[]): AlertTrigger[] {
  return triggers.filter(trigger => trigger.alertId === alertId);
}

/**
 * Get recent triggers
 */
export function getRecentTriggers(triggers: AlertTrigger[], hours: number = 24): AlertTrigger[] {
  const cutoffTime = new Date(Date.now() - hours * 60 * 60 * 1000);
  return triggers.filter(trigger => trigger.triggeredAt >= cutoffTime);
}

/**
 * Get alert statistics
 */
export function getAlertStats(alerts: ReportAlert[], triggers: AlertTrigger[]): AlertStats {
  const criticalAlerts = alerts.filter(a => a.severity === 'critical').length;
  const unacknowledgedTriggers = getUnacknowledgedTriggers(triggers);

  const responseTimes = unacknowledgedTriggers
    .filter(t => t.acknowledgedAt)
    .map(t => t.acknowledgedAt!.getTime() - t.triggeredAt.getTime());

  const averageResponseTime =
    responseTimes.length > 0
      ? responseTimes.reduce((a, b) => a + b) / responseTimes.length / 1000 / 60
      : 0;

  return {
    totalAlerts: alerts.length,
    enabledAlerts: alerts.filter(a => a.enabled).length,
    disabledAlerts: alerts.filter(a => !a.enabled).length,
    totalTriggers: triggers.length,
    unacknowledgedTriggers: unacknowledgedTriggers.length,
    criticalAlerts,
    averageResponseTime: Math.round(averageResponseTime),
  };
}

/**
 * Get alert recommendations
 */
export function getAlertRecommendations(reportType: string): Array<{
  name: string;
  metric: string;
  condition: AlertCondition;
  threshold: number;
  severity: AlertSeverity;
  description: string;
}> {
  const recommendations: Record<string, any[]> = {
    payment: [
      {
        name: 'High Fraud Rate',
        metric: 'fraudRate',
        condition: 'exceeds',
        threshold: 2,
        severity: 'critical',
        description: 'Alert when fraud rate exceeds 2%',
      },
      {
        name: 'Low Success Rate',
        metric: 'successRate',
        condition: 'fallsBelow',
        threshold: 90,
        severity: 'high',
        description: 'Alert when payment success rate falls below 90%',
      },
      {
        name: 'Revenue Spike',
        metric: 'totalRevenue',
        condition: 'exceeds',
        threshold: 200000,
        severity: 'low',
        description: 'Alert when daily revenue exceeds $200,000',
      },
    ],
    reconciliation: [
      {
        name: 'Reconciliation Mismatch',
        metric: 'matchRate',
        condition: 'fallsBelow',
        threshold: 99,
        severity: 'high',
        description: 'Alert when match rate falls below 99%',
      },
      {
        name: 'High Discrepancies',
        metric: 'discrepancies',
        condition: 'exceeds',
        threshold: 100,
        severity: 'medium',
        description: 'Alert when discrepancies exceed 100',
      },
    ],
    withdrawal: [
      {
        name: 'High Pending Withdrawals',
        metric: 'pendingAmount',
        condition: 'exceeds',
        threshold: 50000,
        severity: 'medium',
        description: 'Alert when pending withdrawals exceed $50,000',
      },
      {
        name: 'Slow Processing',
        metric: 'averageProcessingTime',
        condition: 'exceeds',
        threshold: 24,
        severity: 'high',
        description: 'Alert when average processing time exceeds 24 hours',
      },
    ],
  };

  return recommendations[reportType] || [];
}

/**
 * Bulk create alerts from template
 */
export function bulkCreateAlertsFromTemplate(
  reportId: string,
  template: string,
  recipients: string[]
): ReportAlert[] {
  const recommendations = getAlertRecommendations(template);

  return recommendations.map(rec =>
    createReportAlert(
      reportId,
      rec.name,
      rec.metric,
      rec.condition,
      rec.threshold,
      rec.severity,
      ['email', 'push'],
      recipients
    )
  );
}

/**
 * Get alert audit log
 */
export function getAlertAuditLog(alertId: string, triggers: AlertTrigger[]) {
  const alertTriggers = getTriggersForAlert(alertId, triggers);

  return {
    alertId,
    totalTriggers: alertTriggers.length,
    acknowledgedTriggers: alertTriggers.filter(t => t.acknowledged).length,
    auditLog: alertTriggers
      .sort((a, b) => b.triggeredAt.getTime() - a.triggeredAt.getTime())
      .slice(0, 50)
      .map(trigger => ({
        id: trigger.id,
        triggeredAt: trigger.triggeredAt,
        severity: trigger.severity,
        value: trigger.currentValue,
        threshold: trigger.threshold,
        acknowledged: trigger.acknowledged,
        acknowledgedBy: trigger.acknowledgedBy,
        acknowledgedAt: trigger.acknowledgedAt,
      })),
  };
}
