/**
 * Email & SMS Notifications System
 * Integration with Brevo for email and Twilio for SMS delivery
 */

export type NotificationChannel = 'email' | 'sms' | 'both';
export type NotificationTemplate = 'welcome' | 'deposit_confirmation' | 'withdrawal_confirmation' | 'bonus_awarded' | 'tournament_invite' | 'kyc_reminder' | 'responsible_gaming' | 'account_alert';
export type NotificationStatus = 'pending' | 'sent' | 'delivered' | 'failed' | 'bounced';

export interface EmailNotification {
  id: string;
  playerId: number;
  email: string;
  template: NotificationTemplate;
  subject: string;
  body: string;
  htmlBody?: string;
  attachments?: Array<{
    filename: string;
    content: string;
    contentType: string;
  }>;
  status: NotificationStatus;
  sentAt?: Date;
  deliveredAt?: Date;
  failureReason?: string;
  retryCount: number;
  maxRetries: number;
  createdAt: Date;
}

export interface SMSNotification {
  id: string;
  playerId: number;
  phoneNumber: string;
  template: NotificationTemplate;
  message: string;
  status: NotificationStatus;
  sentAt?: Date;
  deliveredAt?: Date;
  failureReason?: string;
  retryCount: number;
  maxRetries: number;
  createdAt: Date;
}

export interface NotificationPreferences {
  playerId: number;
  emailNotifications: boolean;
  smsNotifications: boolean;
  pushNotifications: boolean;
  marketingEmails: boolean;
  responsibleGamingAlerts: boolean;
  transactionAlerts: boolean;
  weeklyReport: boolean;
  unsubscribeToken: string;
  createdAt: Date;
  updatedAt: Date;
}

export interface NotificationTemplate {
  id: string;
  name: NotificationTemplate;
  emailSubject: string;
  emailTemplate: string;
  smsTemplate: string;
  variables: string[];
  category: 'transactional' | 'marketing' | 'alert' | 'report';
  priority: 'high' | 'normal' | 'low';
  createdAt: Date;
}

export interface NotificationLog {
  id: string;
  playerId: number;
  channel: NotificationChannel;
  template: NotificationTemplate;
  status: NotificationStatus;
  sentAt: Date;
  deliveredAt?: Date;
  failureReason?: string;
}

export interface BrevoConfig {
  apiKey: string;
  senderEmail: string;
  senderName: string;
  replyToEmail: string;
}

export interface TwilioConfig {
  accountSid: string;
  authToken: string;
  fromPhoneNumber: string;
}

/**
 * Create email notification
 */
export function createEmailNotification(
  playerId: number,
  email: string,
  template: NotificationTemplate,
  subject: string,
  body: string,
  htmlBody?: string
): EmailNotification {
  return {
    id: `email_${playerId}_${Date.now()}`,
    playerId,
    email,
    template,
    subject,
    body,
    htmlBody,
    status: 'pending',
    retryCount: 0,
    maxRetries: 3,
    createdAt: new Date(),
  };
}

/**
 * Create SMS notification
 */
export function createSMSNotification(
  playerId: number,
  phoneNumber: string,
  template: NotificationTemplate,
  message: string
): SMSNotification {
  return {
    id: `sms_${playerId}_${Date.now()}`,
    playerId,
    phoneNumber,
    template,
    message,
    status: 'pending',
    retryCount: 0,
    maxRetries: 3,
    createdAt: new Date(),
  };
}

/**
 * Send email via Brevo
 */
export async function sendEmailViaBrevo(
  notification: EmailNotification,
  config: BrevoConfig
): Promise<{ success: boolean; messageId?: string; error?: string }> {
  try {
    // Simulate Brevo API call
    const response = await fetch('https://api.brevo.com/v3/smtp/email', {
      method: 'POST',
      headers: {
        'api-key': config.apiKey,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        sender: {
          name: config.senderName,
          email: config.senderEmail,
        },
        to: [
          {
            email: notification.email,
          },
        ],
        subject: notification.subject,
        htmlContent: notification.htmlBody || notification.body,
        replyTo: {
          email: config.replyToEmail,
        },
      }),
    });

    if (response.ok) {
      const data = await response.json() as { id: string };
      notification.status = 'sent';
      notification.sentAt = new Date();
      return { success: true, messageId: data.id };
    } else {
      notification.status = 'failed';
      notification.failureReason = 'Brevo API error';
      notification.retryCount++;
      return { success: false, error: 'Failed to send email' };
    }
  } catch (error) {
    notification.status = 'failed';
    notification.failureReason = (error as Error).message;
    notification.retryCount++;
    return { success: false, error: (error as Error).message };
  }
}

/**
 * Send SMS via Twilio
 */
export async function sendSMSViaTwilio(
  notification: SMSNotification,
  config: TwilioConfig
): Promise<{ success: boolean; messageId?: string; error?: string }> {
  try {
    // Simulate Twilio API call
    const auth = Buffer.from(`${config.accountSid}:${config.authToken}`).toString('base64');
    const response = await fetch(
      `https://api.twilio.com/2010-04-01/Accounts/${config.accountSid}/Messages.json`,
      {
        method: 'POST',
        headers: {
          'Authorization': `Basic ${auth}`,
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: new URLSearchParams({
          From: config.fromPhoneNumber,
          To: notification.phoneNumber,
          Body: notification.message,
        }).toString(),
      }
    );

    if (response.ok) {
      const data = await response.json() as { sid: string };
      notification.status = 'sent';
      notification.sentAt = new Date();
      return { success: true, messageId: data.sid };
    } else {
      notification.status = 'failed';
      notification.failureReason = 'Twilio API error';
      notification.retryCount++;
      return { success: false, error: 'Failed to send SMS' };
    }
  } catch (error) {
    notification.status = 'failed';
    notification.failureReason = (error as Error).message;
    notification.retryCount++;
    return { success: false, error: (error as Error).message };
  }
}

/**
 * Create notification preferences
 */
export function createNotificationPreferences(playerId: number): NotificationPreferences {
  return {
    playerId,
    emailNotifications: true,
    smsNotifications: true,
    pushNotifications: true,
    marketingEmails: true,
    responsibleGamingAlerts: true,
    transactionAlerts: true,
    weeklyReport: true,
    unsubscribeToken: generateUnsubscribeToken(),
    createdAt: new Date(),
    updatedAt: new Date(),
  };
}

/**
 * Generate unsubscribe token
 */
function generateUnsubscribeToken(): string {
  return `unsub_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}

/**
 * Update notification preferences
 */
export function updateNotificationPreferences(
  preferences: NotificationPreferences,
  updates: Partial<NotificationPreferences>
): void {
  Object.assign(preferences, updates);
  preferences.updatedAt = new Date();
}

/**
 * Predefined email templates
 */
export const EMAIL_TEMPLATES: Record<NotificationTemplate, { subject: string; body: string }> = {
  welcome: {
    subject: 'Welcome to CoinKrazy!',
    body: 'Welcome {{playerName}}! Start playing and win big today.',
  },
  deposit_confirmation: {
    subject: 'Deposit Confirmed',
    body: 'Your deposit of {{amount}} has been confirmed. Your new balance is {{newBalance}}.',
  },
  withdrawal_confirmation: {
    subject: 'Withdrawal Processed',
    body: 'Your withdrawal of {{amount}} has been processed. It will arrive in 1-3 business days.',
  },
  bonus_awarded: {
    subject: 'Bonus Awarded!',
    body: 'Congratulations! You have been awarded {{bonusAmount}} bonus credits.',
  },
  tournament_invite: {
    subject: 'You\'re Invited to {{tournamentName}}!',
    body: 'Join {{tournamentName}} and compete for {{prizePool}} in prizes!',
  },
  kyc_reminder: {
    subject: 'Complete Your Verification',
    body: 'Please complete your KYC verification to continue playing.',
  },
  responsible_gaming: {
    subject: 'Responsible Gaming Reminder',
    body: 'Please remember to play responsibly. Set your limits today.',
  },
  account_alert: {
    subject: 'Account Alert',
    body: 'There has been unusual activity on your account. Please review your account settings.',
  },
};

/**
 * Predefined SMS templates
 */
export const SMS_TEMPLATES: Record<NotificationTemplate, string> = {
  welcome: 'Welcome to CoinKrazy! Start playing now: {{link}}',
  deposit_confirmation: 'Deposit confirmed: {{amount}}. New balance: {{newBalance}}',
  withdrawal_confirmation: 'Withdrawal {{amount}} processing. Arrives in 1-3 days.',
  bonus_awarded: 'Bonus awarded! {{bonusAmount}} credits added to your account.',
  tournament_invite: 'Join {{tournamentName}}! {{prizePool}} in prizes. {{link}}',
  kyc_reminder: 'Complete your KYC verification: {{link}}',
  responsible_gaming: 'Play responsibly. Set your limits: {{link}}',
  account_alert: 'Unusual activity detected. Review: {{link}}',
};

/**
 * Notification batch processor
 */
export interface NotificationBatch {
  id: string;
  notifications: Array<EmailNotification | SMSNotification>;
  status: 'pending' | 'processing' | 'completed' | 'failed';
  createdAt: Date;
  processedAt?: Date;
  failureCount: number;
  successCount: number;
}

export function createNotificationBatch(
  notifications: Array<EmailNotification | SMSNotification>
): NotificationBatch {
  return {
    id: `batch_${Date.now()}`,
    notifications,
    status: 'pending',
    createdAt: new Date(),
    failureCount: 0,
    successCount: 0,
  };
}

/**
 * Notification statistics
 */
export interface NotificationStats {
  totalSent: number;
  totalDelivered: number;
  totalFailed: number;
  totalBounced: number;
  deliveryRate: number; // percentage
  bounceRate: number; // percentage
  failureRate: number; // percentage
  averageDeliveryTime: number; // seconds
}

export function calculateNotificationStats(
  logs: NotificationLog[]
): NotificationStats {
  const total = logs.length;
  const delivered = logs.filter((l) => l.status === 'delivered').length;
  const failed = logs.filter((l) => l.status === 'failed').length;
  const bounced = logs.filter((l) => l.status === 'bounced').length;

  const deliveryTimes = logs
    .filter((l) => l.deliveredAt && l.sentAt)
    .map((l) => (l.deliveredAt!.getTime() - l.sentAt.getTime()) / 1000);

  const avgDeliveryTime =
    deliveryTimes.length > 0
      ? deliveryTimes.reduce((a, b) => a + b, 0) / deliveryTimes.length
      : 0;

  return {
    totalSent: total,
    totalDelivered: delivered,
    totalFailed: failed,
    totalBounced: bounced,
    deliveryRate: total > 0 ? (delivered / total) * 100 : 0,
    bounceRate: total > 0 ? (bounced / total) * 100 : 0,
    failureRate: total > 0 ? (failed / total) * 100 : 0,
    averageDeliveryTime: avgDeliveryTime,
  };
}

/**
 * Unsubscribe from notifications
 */
export function unsubscribeFromNotifications(
  preferences: NotificationPreferences,
  channel: 'email' | 'sms' | 'all'
): void {
  if (channel === 'email' || channel === 'all') {
    preferences.emailNotifications = false;
    preferences.marketingEmails = false;
  }

  if (channel === 'sms' || channel === 'all') {
    preferences.smsNotifications = false;
  }

  preferences.updatedAt = new Date();
}
