/**
 * Mobile App Alert Notifications
 * Push alerts to admin mobile app with quick actions
 */

export type NotificationAction = 'acknowledge' | 'dismiss' | 'view' | 'snooze';
export type NotificationPriority = 'max' | 'high' | 'default' | 'low' | 'min';

export interface MobileNotification {
  id: string;
  alertId: string;
  userId: string;
  title: string;
  body: string;
  severity: 'critical' | 'high' | 'medium' | 'low';
  priority: NotificationPriority;
  data: Record<string, any>;
  actions: NotificationAction[];
  sentAt: Date;
  deliveredAt?: Date;
  interactedAt?: Date;
  interactionType?: NotificationAction;
  badge: number;
  sound: string;
  vibrate: number[];
  icon: string;
  color: string;
  ttl: number; // Time to live in seconds
}

export interface NotificationDeliveryLog {
  id: string;
  notificationId: string;
  userId: string;
  deviceId: string;
  platform: 'ios' | 'android' | 'web';
  status: 'pending' | 'sent' | 'delivered' | 'failed';
  sentAt: Date;
  deliveredAt?: Date;
  failureReason?: string;
  retryCount: number;
}

export interface MobileAlertSettings {
  userId: string;
  enableCriticalAlerts: boolean;
  enableHighAlerts: boolean;
  enableMediumAlerts: boolean;
  enableLowAlerts: boolean;
  quietHoursStart: string; // HH:mm format
  quietHoursEnd: string;
  soundEnabled: boolean;
  vibrateEnabled: boolean;
  ledEnabled: boolean;
  groupNotifications: boolean;
  maxNotificationsPerHour: number;
}

/**
 * Create mobile notification
 */
export function createMobileNotification(
  alertId: string,
  userId: string,
  title: string,
  body: string,
  severity: 'critical' | 'high' | 'medium' | 'low',
  data: Record<string, any>,
  actions: NotificationAction[] = ['acknowledge', 'dismiss', 'view']
): MobileNotification {
  const severityConfig = {
    critical: {
      priority: 'max' as NotificationPriority,
      sound: 'alert_critical',
      vibrate: [500, 200, 500],
      color: '#dc2626',
      icon: 'alert_critical',
    },
    high: {
      priority: 'high' as NotificationPriority,
      sound: 'alert_high',
      vibrate: [300, 100, 300],
      color: '#ea580c',
      icon: 'alert_high',
    },
    medium: {
      priority: 'default' as NotificationPriority,
      sound: 'alert_medium',
      vibrate: [200, 100],
      color: '#eab308',
      icon: 'alert_medium',
    },
    low: {
      priority: 'low' as NotificationPriority,
      sound: 'alert_low',
      vibrate: [100],
      color: '#06b6d4',
      icon: 'alert_low',
    },
  };

  const config = severityConfig[severity];

  return {
    id: `NOTIF-${Date.now()}`,
    alertId,
    userId,
    title,
    body,
    severity,
    priority: config.priority,
    data,
    actions,
    sentAt: new Date(),
    badge: 1,
    sound: config.sound,
    vibrate: config.vibrate,
    icon: config.icon,
    color: config.color,
    ttl: severity === 'critical' ? 86400 : 3600, // 24h for critical, 1h for others
  };
}

/**
 * Check if notification should be sent based on quiet hours
 */
export function shouldSendNotification(
  settings: MobileAlertSettings,
  severity: 'critical' | 'high' | 'medium' | 'low'
): boolean {
  // Critical alerts always go through
  if (severity === 'critical') return true;

  // Check if alert type is enabled
  const enabledMap = {
    critical: settings.enableCriticalAlerts,
    high: settings.enableHighAlerts,
    medium: settings.enableMediumAlerts,
    low: settings.enableLowAlerts,
  };

  if (!enabledMap[severity]) return false;

  // Check quiet hours
  const now = new Date();
  const currentTime = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;

  const [quietStart] = settings.quietHoursStart.split(':').map(Number);
  const [quietEnd] = settings.quietHoursEnd.split(':').map(Number);
  const [currentHour] = currentTime.split(':').map(Number);

  // If quiet hours span midnight (e.g., 22:00 to 08:00)
  if (quietStart > quietEnd) {
    if (currentHour >= quietStart || currentHour < quietEnd) {
      return severity === 'critical'; // Only critical during quiet hours
    }
  } else {
    // Normal quiet hours (e.g., 22:00 to 08:00 same day)
    if (currentHour >= quietStart && currentHour < quietEnd) {
      return severity === 'critical';
    }
  }

  return true;
}

/**
 * Create delivery log
 */
export function createDeliveryLog(
  notification: MobileNotification,
  deviceId: string,
  platform: 'ios' | 'android' | 'web'
): NotificationDeliveryLog {
  return {
    id: `LOG-${Date.now()}`,
    notificationId: notification.id,
    userId: notification.userId,
    deviceId,
    platform,
    status: 'pending',
    sentAt: new Date(),
    retryCount: 0,
  };
}

/**
 * Mark notification as delivered
 */
export function markAsDelivered(log: NotificationDeliveryLog): NotificationDeliveryLog {
  return {
    ...log,
    status: 'delivered',
    deliveredAt: new Date(),
  };
}

/**
 * Mark notification as failed
 */
export function markAsFailed(
  log: NotificationDeliveryLog,
  reason: string,
  retryCount: number
): NotificationDeliveryLog {
  return {
    ...log,
    status: 'failed',
    failureReason: reason,
    retryCount,
  };
}

/**
 * Record notification interaction
 */
export function recordInteraction(
  notification: MobileNotification,
  action: NotificationAction
): MobileNotification {
  return {
    ...notification,
    interactedAt: new Date(),
    interactionType: action,
  };
}

/**
 * Get notification payload for FCM (Firebase Cloud Messaging)
 */
export function getFCMPayload(notification: MobileNotification) {
  return {
    notification: {
      title: notification.title,
      body: notification.body,
      sound: notification.sound,
      icon: notification.icon,
      color: notification.color,
    },
    data: {
      alertId: notification.alertId,
      severity: notification.severity,
      priority: notification.priority,
      ...notification.data,
    },
    android: {
      priority: notification.priority === 'max' ? 'high' : 'normal',
      notification: {
        sound: notification.sound,
        icon: notification.icon,
        color: notification.color,
        vibrate: notification.vibrate,
        click_action: 'FLUTTER_NOTIFICATION_CLICK',
      },
    },
    apns: {
      headers: {
        'apns-priority': notification.priority === 'max' ? '10' : '10',
      },
      payload: {
        aps: {
          alert: {
            title: notification.title,
            body: notification.body,
          },
          sound: notification.sound,
          badge: notification.badge,
          'mutable-content': true,
        },
      },
    },
    webpush: {
      notification: {
        title: notification.title,
        body: notification.body,
        icon: notification.icon,
        badge: notification.icon,
        tag: notification.alertId,
        requireInteraction: notification.priority === 'max',
      },
      data: notification.data,
    },
    ttl: notification.ttl,
  };
}

/**
 * Get notification payload for APNs (Apple Push Notification service)
 */
export function getAPNsPayload(notification: MobileNotification) {
  return {
    aps: {
      alert: {
        title: notification.title,
        body: notification.body,
      },
      sound: notification.sound,
      badge: notification.badge,
      'mutable-content': true,
      'custom-key': notification.data,
    },
    alertId: notification.alertId,
    severity: notification.severity,
  };
}

/**
 * Create default mobile alert settings
 */
export function createDefaultSettings(userId: string): MobileAlertSettings {
  return {
    userId,
    enableCriticalAlerts: true,
    enableHighAlerts: true,
    enableMediumAlerts: true,
    enableLowAlerts: false,
    quietHoursStart: '22:00',
    quietHoursEnd: '08:00',
    soundEnabled: true,
    vibrateEnabled: true,
    ledEnabled: true,
    groupNotifications: true,
    maxNotificationsPerHour: 10,
  };
}

/**
 * Get notification statistics
 */
export function getNotificationStats(
  notifications: MobileNotification[],
  logs: NotificationDeliveryLog[]
) {
  const totalSent = logs.length;
  const delivered = logs.filter(l => l.status === 'delivered').length;
  const failed = logs.filter(l => l.status === 'failed').length;
  const pending = logs.filter(l => l.status === 'pending').length;

  const interacted = notifications.filter(n => n.interactedAt).length;
  const acknowledged = notifications.filter(n => n.interactionType === 'acknowledge').length;
  const dismissed = notifications.filter(n => n.interactionType === 'dismiss').length;

  return {
    totalSent,
    delivered,
    failed,
    pending,
    deliveryRate: totalSent > 0 ? (delivered / totalSent) * 100 : 0,
    failureRate: totalSent > 0 ? (failed / totalSent) * 100 : 0,
    interactionRate: notifications.length > 0 ? (interacted / notifications.length) * 100 : 0,
    acknowledged,
    dismissed,
    snoozed: notifications.filter(n => n.interactionType === 'snooze').length,
  };
}

/**
 * Get notifications by severity
 */
export function getNotificationsBySeverity(
  severity: 'critical' | 'high' | 'medium' | 'low',
  notifications: MobileNotification[]
): MobileNotification[] {
  return notifications.filter(n => n.severity === severity);
}

/**
 * Get unread notifications
 */
export function getUnreadNotifications(notifications: MobileNotification[]): MobileNotification[] {
  return notifications.filter(n => !n.interactedAt);
}

/**
 * Get notifications for user
 */
export function getNotificationsForUser(
  userId: string,
  notifications: MobileNotification[]
): MobileNotification[] {
  return notifications.filter(n => n.userId === userId);
}

/**
 * Batch send notifications
 */
export async function batchSendNotifications(
  notifications: MobileNotification[],
  deviceTokens: Map<string, string[]>
): Promise<{ sent: number; failed: number; logs: NotificationDeliveryLog[] }> {
  const logs: NotificationDeliveryLog[] = [];
  let sent = 0;
  let failed = 0;

  for (const notification of notifications) {
    const tokens = deviceTokens.get(notification.userId) || [];

    for (const token of tokens) {
      try {
        // In production, send via FCM/APNs
        const log = createDeliveryLog(notification, token, 'android');
        logs.push(markAsDelivered(log));
        sent++;

        console.log(`[Mobile Notifications] Sent notification ${notification.id} to ${token}`);
      } catch (error) {
        const log = createDeliveryLog(notification, token, 'android');
        logs.push(markAsFailed(log, error instanceof Error ? error.message : 'Unknown error', 0));
        failed++;

        console.error(`[Mobile Notifications] Failed to send notification ${notification.id}:`, error);
      }
    }
  }

  return { sent, failed, logs };
}

/**
 * Get notification template
 */
export function getNotificationTemplate(
  alertType: string,
  severity: 'critical' | 'high' | 'medium' | 'low'
): { title: string; body: string } {
  const templates: Record<string, Record<string, { title: string; body: string }>> = {
    fraud: {
      critical: {
        title: '🚨 Critical Fraud Alert',
        body: 'Suspicious activity detected. Immediate action required.',
      },
      high: {
        title: '⚠️ High Fraud Risk',
        body: 'Multiple fraud indicators detected.',
      },
      medium: {
        title: '⚡ Fraud Alert',
        body: 'Potential fraud detected. Review recommended.',
      },
      low: {
        title: 'ℹ️ Fraud Notice',
        body: 'Minor fraud indicators detected.',
      },
    },
    revenue: {
      critical: {
        title: '📊 Revenue Alert',
        body: 'Significant revenue change detected.',
      },
      high: {
        title: '📈 Revenue Update',
        body: 'Notable revenue trend detected.',
      },
      medium: {
        title: '💰 Revenue Notice',
        body: 'Revenue metric update available.',
      },
      low: {
        title: 'ℹ️ Revenue Info',
        body: 'Revenue data updated.',
      },
    },
    withdrawal: {
      critical: {
        title: '💸 Withdrawal Alert',
        body: 'High-value withdrawal pending approval.',
      },
      high: {
        title: '📤 Withdrawal Notice',
        body: 'Multiple withdrawals pending.',
      },
      medium: {
        title: '📤 Withdrawal Update',
        body: 'Withdrawal requests available for review.',
      },
      low: {
        title: 'ℹ️ Withdrawal Info',
        body: 'Withdrawal data updated.',
      },
    },
  };

  return templates[alertType]?.[severity] || {
    title: 'Alert',
    body: 'New alert available',
  };
}
