/**
 * Payment Notifications System
 * Send SMS/Email alerts for payment events
 */

export interface PaymentNotification {
  id: string;
  userId: number;
  type: 'payment_failed' | 'retry_scheduled' | 'retry_success' | 'payment_success' | 'payment_cancelled' | 'dispute_created' | 'dispute_resolved' | 'refund_processed';
  channel: 'email' | 'sms' | 'both';
  transactionId: string;
  amount: number;
  status: 'pending' | 'sent' | 'failed' | 'delivered';
  message: string;
  emailAddress?: string;
  phoneNumber?: string;
  sentAt?: Date;
  deliveredAt?: Date;
  error?: string;
  createdAt: Date;
  metadata: Record<string, any>;
}

export interface NotificationTemplate {
  type: PaymentNotification['type'];
  emailSubject: string;
  emailBody: string;
  smsBody: string;
  variables: string[];
}

// Notification templates
export const NOTIFICATION_TEMPLATES: Record<string, NotificationTemplate> = {
  payment_failed: {
    type: 'payment_failed',
    emailSubject: 'Payment Failed - Action Required',
    emailBody: `
Dear {{userName}},

Your payment of {{amount}} SC failed. This could be due to:
- Insufficient funds
- Card declined
- Network error

We will automatically retry your payment in 24 hours. If you'd like to retry immediately, please visit your wallet.

Transaction ID: {{transactionId}}
Date: {{date}}

If you need assistance, contact support@coinkrazy.com

Best regards,
CoinKrazy Team
    `,
    smsBody: 'Your payment of {{amount}} SC failed. We\'ll retry in 24 hours. Visit wallet to retry now. Need help? Reply SUPPORT',
    variables: ['userName', 'amount', 'transactionId', 'date'],
  },

  retry_scheduled: {
    type: 'retry_scheduled',
    emailSubject: 'Payment Retry Scheduled',
    emailBody: `
Dear {{userName}},

Your payment of {{amount}} SC is scheduled for retry on {{retryDate}}.

Transaction ID: {{transactionId}}
Attempt: {{attempt}}/3

If you want to update your payment method, visit your wallet settings.

Best regards,
CoinKrazy Team
    `,
    smsBody: 'Payment retry scheduled for {{retryDate}}. Update payment method in wallet if needed.',
    variables: ['userName', 'amount', 'retryDate', 'transactionId', 'attempt'],
  },

  retry_success: {
    type: 'retry_success',
    emailSubject: 'Payment Successful - Coins Delivered!',
    emailBody: `
Dear {{userName}},

Great news! Your payment retry was successful!

Amount: {{amount}} SC
Transaction ID: {{transactionId}}
Date: {{date}}

Your coins have been added to your account. Enjoy playing!

Best regards,
CoinKrazy Team
    `,
    smsBody: 'Payment successful! {{amount}} SC added to your account. Start playing now!',
    variables: ['userName', 'amount', 'transactionId', 'date'],
  },

  payment_success: {
    type: 'payment_success',
    emailSubject: 'Payment Successful - Coins Added!',
    emailBody: `
Dear {{userName}},

Your payment has been processed successfully!

Amount: {{amount}} SC
Transaction ID: {{transactionId}}
Date: {{date}}

Your coins are now available in your wallet. Start playing!

Best regards,
CoinKrazy Team
    `,
    smsBody: 'Payment successful! {{amount}} SC added. Start playing now!',
    variables: ['userName', 'amount', 'transactionId', 'date'],
  },

  payment_cancelled: {
    type: 'payment_cancelled',
    emailSubject: 'Payment Cancelled',
    emailBody: `
Dear {{userName}},

Your payment has been cancelled.

Amount: {{amount}} SC
Transaction ID: {{transactionId}}
Reason: {{reason}}

If you'd like to try again, visit your wallet.

Best regards,
CoinKrazy Team
    `,
    smsBody: 'Payment cancelled. Reason: {{reason}}. Try again in wallet.',
    variables: ['userName', 'amount', 'transactionId', 'reason'],
  },

  dispute_created: {
    type: 'dispute_created',
    emailSubject: 'Payment Dispute Opened',
    emailBody: `
Dear {{userName}},

A payment dispute has been opened for your transaction.

Amount: {{amount}} SC
Transaction ID: {{transactionId}}
Dispute ID: {{disputeId}}

Our team will review this within 24-48 hours. You'll receive updates via email.

Best regards,
CoinKrazy Support Team
    `,
    smsBody: 'Payment dispute opened. Dispute ID: {{disputeId}}. We\'ll review within 24-48 hours.',
    variables: ['userName', 'amount', 'transactionId', 'disputeId'],
  },

  dispute_resolved: {
    type: 'dispute_resolved',
    emailSubject: 'Payment Dispute Resolved',
    emailBody: `
Dear {{userName}},

Your payment dispute has been resolved.

Transaction ID: {{transactionId}}
Dispute ID: {{disputeId}}
Resolution: {{resolution}}
Amount Refunded: {{refundAmount}} SC

The refund will be processed within 3-5 business days.

Best regards,
CoinKrazy Support Team
    `,
    smsBody: 'Dispute resolved! {{refundAmount}} SC refund processing. 3-5 business days.',
    variables: ['userName', 'transactionId', 'disputeId', 'resolution', 'refundAmount'],
  },

  refund_processed: {
    type: 'refund_processed',
    emailSubject: 'Refund Processed',
    emailBody: `
Dear {{userName}},

Your refund has been processed!

Amount: {{amount}} SC
Transaction ID: {{transactionId}}
Refund Date: {{date}}

The funds should appear in your account within 3-5 business days.

Best regards,
CoinKrazy Support Team
    `,
    smsBody: 'Refund processed! {{amount}} SC. Check account in 3-5 business days.',
    variables: ['userName', 'amount', 'transactionId', 'date'],
  },
};

/**
 * Create payment notification
 */
export function createNotification(
  userId: number,
  type: PaymentNotification['type'],
  transactionId: string,
  amount: number,
  channel: 'email' | 'sms' | 'both',
  emailAddress?: string,
  phoneNumber?: string,
  metadata: Record<string, any> = {}
): PaymentNotification {
  const template = NOTIFICATION_TEMPLATES[type];
  const message = template.emailBody;

  return {
    id: `NOTIF-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
    userId,
    type,
    channel,
    transactionId,
    amount,
    status: 'pending',
    message,
    emailAddress,
    phoneNumber,
    createdAt: new Date(),
    metadata,
  };
}

/**
 * Render notification with variables
 */
export function renderNotification(
  template: NotificationTemplate,
  variables: Record<string, any>
): { subject: string; emailBody: string; smsBody: string } {
  let subject = template.emailSubject;
  let emailBody = template.emailBody;
  let smsBody = template.smsBody;

  template.variables.forEach(variable => {
    const value = variables[variable] || '';
    const regex = new RegExp(`{{${variable}}}`, 'g');
    subject = subject.replace(regex, String(value));
    emailBody = emailBody.replace(regex, String(value));
    smsBody = smsBody.replace(regex, String(value));
  });

  return { subject, emailBody, smsBody };
}

/**
 * Send email notification
 */
export async function sendEmailNotification(
  notification: PaymentNotification,
  emailAddress: string,
  variables: Record<string, any>
): Promise<boolean> {
  try {
    const template = NOTIFICATION_TEMPLATES[notification.type];
    const { subject, emailBody } = renderNotification(template, variables);

    // In production, integrate with Brevo email service
    console.log(`[Email] Sending to ${emailAddress}`);
    console.log(`Subject: ${subject}`);
    console.log(`Body: ${emailBody}`);

    return true;
  } catch (error) {
    console.error('[Email] Error sending notification:', error);
    return false;
  }
}

/**
 * Send SMS notification
 */
export async function sendSMSNotification(
  notification: PaymentNotification,
  phoneNumber: string,
  variables: Record<string, any>
): Promise<boolean> {
  try {
    const template = NOTIFICATION_TEMPLATES[notification.type];
    const { smsBody } = renderNotification(template, variables);

    // In production, integrate with Twilio SMS service
    console.log(`[SMS] Sending to ${phoneNumber}`);
    console.log(`Message: ${smsBody}`);

    return true;
  } catch (error) {
    console.error('[SMS] Error sending notification:', error);
    return false;
  }
}

/**
 * Mark notification as sent
 */
export function markAsSent(notification: PaymentNotification): PaymentNotification {
  return {
    ...notification,
    status: 'sent',
    sentAt: new Date(),
  };
}

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

/**
 * Mark notification as failed
 */
export function markAsFailed(
  notification: PaymentNotification,
  error: string
): PaymentNotification {
  return {
    ...notification,
    status: 'failed',
    error,
  };
}

/**
 * Get notification statistics
 */
export interface NotificationStats {
  total: number;
  pending: number;
  sent: number;
  delivered: number;
  failed: number;
  deliveryRate: number;
  byType: Record<string, number>;
  byChannel: Record<string, number>;
}

export function getNotificationStats(notifications: PaymentNotification[]): NotificationStats {
  const pending = notifications.filter(n => n.status === 'pending').length;
  const sent = notifications.filter(n => n.status === 'sent').length;
  const delivered = notifications.filter(n => n.status === 'delivered').length;
  const failed = notifications.filter(n => n.status === 'failed').length;

  const byType: Record<string, number> = {};
  const byChannel: Record<string, number> = {};

  notifications.forEach(n => {
    byType[n.type] = (byType[n.type] || 0) + 1;
    byChannel[n.channel] = (byChannel[n.channel] || 0) + 1;
  });

  const deliveryRate = notifications.length > 0 ? (delivered / notifications.length) * 100 : 0;

  return {
    total: notifications.length,
    pending,
    sent,
    delivered,
    failed,
    deliveryRate,
    byType,
    byChannel,
  };
}

/**
 * Export notifications to CSV
 */
export function exportNotificationsToCSV(notifications: PaymentNotification[]): string {
  const headers = [
    'Notification ID',
    'User ID',
    'Type',
    'Channel',
    'Transaction ID',
    'Amount',
    'Status',
    'Sent At',
    'Delivered At',
    'Error',
  ];

  const rows = notifications.map(n => [
    n.id,
    n.userId,
    n.type,
    n.channel,
    n.transactionId,
    n.amount,
    n.status,
    n.sentAt?.toISOString() || 'N/A',
    n.deliveredAt?.toISOString() || 'N/A',
    n.error || 'N/A',
  ]);

  const csv = [
    headers.join(','),
    ...rows.map(row => row.map(cell => `"${cell}"`).join(',')),
  ].join('\n');

  return csv;
}

/**
 * Retry failed notifications
 */
export function getFailedNotifications(notifications: PaymentNotification[]): PaymentNotification[] {
  return notifications.filter(n => n.status === 'failed');
}

/**
 * Get pending notifications
 */
export function getPendingNotifications(notifications: PaymentNotification[]): PaymentNotification[] {
  return notifications.filter(n => n.status === 'pending');
}

/**
 * Cleanup old notifications
 */
export function cleanupOldNotifications(
  notifications: PaymentNotification[],
  daysOld: number = 30
): PaymentNotification[] {
  const cutoffDate = new Date();
  cutoffDate.setDate(cutoffDate.getDate() - daysOld);

  return notifications.filter(n => n.createdAt > cutoffDate);
}

/**
 * Get notifications by user
 */
export function getNotificationsByUser(
  notifications: PaymentNotification[],
  userId: number
): PaymentNotification[] {
  return notifications.filter(n => n.userId === userId);
}

/**
 * Get notifications by type
 */
export function getNotificationsByType(
  notifications: PaymentNotification[],
  type: PaymentNotification['type']
): PaymentNotification[] {
  return notifications.filter(n => n.type === type);
}

/**
 * Generate notification report
 */
export function generateNotificationReport(notifications: PaymentNotification[]): string {
  const stats = getNotificationStats(notifications);
  const failedNotifications = getFailedNotifications(notifications);

  return `
PAYMENT NOTIFICATION REPORT
Generated: ${new Date().toISOString()}

SUMMARY
-------
Total Notifications: ${stats.total}
Pending: ${stats.pending}
Sent: ${stats.sent}
Delivered: ${stats.delivered}
Failed: ${stats.failed}
Delivery Rate: ${stats.deliveryRate.toFixed(1)}%

BY TYPE
-------
${Object.entries(stats.byType).map(([type, count]) => `- ${type}: ${count}`).join('\n')}

BY CHANNEL
----------
${Object.entries(stats.byChannel).map(([channel, count]) => `- ${channel}: ${count}`).join('\n')}

FAILED NOTIFICATIONS (${failedNotifications.length})
${failedNotifications.slice(-10).map(n => `- ${n.id}: ${n.type} (${n.error})`).join('\n')}

RECOMMENDATIONS
---------------
1. Review and retry failed notifications
2. Monitor delivery rates for each channel
3. Investigate patterns in failed notifications
4. Update notification templates if needed
  `;
}
