/**
 * Email Reputation Monitoring Service
 * Tracks sender reputation metrics and alerts on degradation
 */

export interface DomainAuthConfig {
  spfConfigured: boolean;
  spfRecord?: string;
  dkimConfigured: boolean;
  dkimSelector?: string;
  dmarcConfigured: boolean;
  dmarcPolicy?: 'none' | 'quarantine' | 'reject';
}

export interface ReputationMetrics {
  domain: string;
  bounceRate: number; // percentage
  complaintRate: number; // percentage
  unsubscribeRate: number; // percentage
  spamTrapHits: number; // count
  blacklistStatus: 'clean' | 'listed' | 'warning';
  listedOn: string[]; // blacklist names
  authConfig: DomainAuthConfig;
  lastUpdated: Date;
}

export interface ReputationAlert {
  type: 'critical' | 'warning' | 'info';
  message: string;
  metric: string;
  currentValue: number;
  threshold: number;
  recommendation: string;
}

export interface ReputationScore {
  domain: string;
  score: number; // 0-100
  grade: 'A' | 'B' | 'C' | 'D' | 'F';
  status: 'excellent' | 'good' | 'fair' | 'poor' | 'critical';
  metrics: ReputationMetrics;
  alerts: ReputationAlert[];
  recommendations: string[];
}

/**
 * Calculate reputation score based on metrics
 */
export function calculateReputationScore(metrics: ReputationMetrics): ReputationScore {
  let score = 100;
  const alerts: ReputationAlert[] = [];
  const recommendations: string[] = [];

  // Bounce rate check (ideal: < 2%)
  if (metrics.bounceRate > 5) {
    score -= 25;
    alerts.push({
      type: 'critical',
      message: `High bounce rate: ${metrics.bounceRate.toFixed(2)}%`,
      metric: 'bounceRate',
      currentValue: metrics.bounceRate,
      threshold: 5,
      recommendation: 'Review your list quality and remove invalid addresses',
    });
    recommendations.push('Clean your email list to remove invalid addresses');
  } else if (metrics.bounceRate > 2) {
    score -= 10;
    alerts.push({
      type: 'warning',
      message: `Elevated bounce rate: ${metrics.bounceRate.toFixed(2)}%`,
      metric: 'bounceRate',
      currentValue: metrics.bounceRate,
      threshold: 2,
      recommendation: 'Monitor bounce rate and consider list cleaning',
    });
    recommendations.push('Monitor bounce rate and consider list cleaning');
  }

  // Complaint rate check (ideal: < 0.1%)
  if (metrics.complaintRate > 0.5) {
    score -= 25;
    alerts.push({
      type: 'critical',
      message: `High complaint rate: ${metrics.complaintRate.toFixed(3)}%`,
      metric: 'complaintRate',
      currentValue: metrics.complaintRate,
      threshold: 0.5,
      recommendation: 'Reduce sending volume and improve content relevance',
    });
    recommendations.push('Reduce sending volume and improve content relevance');
  } else if (metrics.complaintRate > 0.1) {
    score -= 15;
    alerts.push({
      type: 'warning',
      message: `Elevated complaint rate: ${metrics.complaintRate.toFixed(3)}%`,
      metric: 'complaintRate',
      currentValue: metrics.complaintRate,
      threshold: 0.1,
      recommendation: 'Review content and ensure compliance with CAN-SPAM',
    });
    recommendations.push('Review content and ensure compliance with CAN-SPAM');
  }

  // Unsubscribe rate check (ideal: < 0.5%)
  if (metrics.unsubscribeRate > 1) {
    score -= 10;
    alerts.push({
      type: 'warning',
      message: `High unsubscribe rate: ${metrics.unsubscribeRate.toFixed(2)}%`,
      metric: 'unsubscribeRate',
      currentValue: metrics.unsubscribeRate,
      threshold: 1,
      recommendation: 'Review email content and frequency',
    });
    recommendations.push('Review email content and frequency');
  }

  // Spam trap hits
  if (metrics.spamTrapHits > 0) {
    score -= 20;
    alerts.push({
      type: 'critical',
      message: `Spam trap hits detected: ${metrics.spamTrapHits}`,
      metric: 'spamTrapHits',
      currentValue: metrics.spamTrapHits,
      threshold: 0,
      recommendation: 'Review list acquisition practices and remove old addresses',
    });
    recommendations.push('Review list acquisition practices and remove old addresses');
  }

  // Blacklist status
  if (metrics.blacklistStatus === 'listed') {
    score -= 30;
    alerts.push({
      type: 'critical',
      message: `Domain listed on blacklist: ${metrics.listedOn.join(', ')}`,
      metric: 'blacklistStatus',
      currentValue: 1,
      threshold: 0,
      recommendation: 'Submit delisting request to affected blacklists immediately',
    });
    recommendations.push('Submit delisting request to affected blacklists immediately');
  } else if (metrics.blacklistStatus === 'warning') {
    score -= 15;
    alerts.push({
      type: 'warning',
      message: 'Domain on blacklist warning list',
      metric: 'blacklistStatus',
      currentValue: 0.5,
      threshold: 0,
      recommendation: 'Monitor blacklist status and improve sending practices',
    });
    recommendations.push('Monitor blacklist status and improve sending practices');
  }

  // Authentication check
  if (!metrics.authConfig.spfConfigured) {
    score -= 10;
    recommendations.push('Configure SPF record for domain authentication');
  }
  if (!metrics.authConfig.dkimConfigured) {
    score -= 10;
    recommendations.push('Configure DKIM for domain signing');
  }
  if (!metrics.authConfig.dmarcConfigured) {
    score -= 10;
    recommendations.push('Configure DMARC policy for domain protection');
  }

  // Ensure score is within bounds
  score = Math.max(0, Math.min(100, score));

  // Determine grade
  let grade: 'A' | 'B' | 'C' | 'D' | 'F';
  if (score >= 90) grade = 'A';
  else if (score >= 80) grade = 'B';
  else if (score >= 70) grade = 'C';
  else if (score >= 60) grade = 'D';
  else grade = 'F';

  // Determine status
  let status: 'excellent' | 'good' | 'fair' | 'poor' | 'critical';
  if (score >= 90) status = 'excellent';
  else if (score >= 80) status = 'good';
  else if (score >= 70) status = 'fair';
  else if (score >= 50) status = 'poor';
  else status = 'critical';

  return {
    domain: metrics.domain,
    score,
    grade,
    status,
    metrics,
    alerts,
    recommendations: [...new Set(recommendations)], // Remove duplicates
  };
}

/**
 * Generate reputation report
 */
export function generateReputationReport(reputationScore: ReputationScore): string {
  const report = `
Email Reputation Report
======================

Domain: ${reputationScore.domain}
Reputation Score: ${reputationScore.score}/100 (Grade: ${reputationScore.grade})
Status: ${reputationScore.status.toUpperCase()}

Metrics:
- Bounce Rate: ${reputationScore.metrics.bounceRate.toFixed(2)}%
- Complaint Rate: ${reputationScore.metrics.complaintRate.toFixed(3)}%
- Unsubscribe Rate: ${reputationScore.metrics.unsubscribeRate.toFixed(2)}%
- Spam Trap Hits: ${reputationScore.metrics.spamTrapHits}
- Blacklist Status: ${reputationScore.metrics.blacklistStatus}

Authentication:
- SPF: ${reputationScore.metrics.authConfig.spfConfigured ? 'Configured' : 'Not Configured'}
- DKIM: ${reputationScore.metrics.authConfig.dkimConfigured ? 'Configured' : 'Not Configured'}
- DMARC: ${reputationScore.metrics.authConfig.dmarcConfigured ? 'Configured' : 'Not Configured'}

${
  reputationScore.alerts.length > 0
    ? `Alerts (${reputationScore.alerts.length}):\n${reputationScore.alerts.map((a) => `- [${a.type.toUpperCase()}] ${a.message}`).join('\n')}`
    : 'No alerts'
}

${
  reputationScore.recommendations.length > 0
    ? `Recommendations:\n${reputationScore.recommendations.map((r) => `- ${r}`).join('\n')}`
    : 'No recommendations'
}

Last Updated: ${reputationScore.metrics.lastUpdated.toISOString()}
  `.trim();

  return report;
}

/**
 * Check if reputation is degrading
 */
export function isReputationDegrading(
  currentScore: ReputationScore,
  previousScore: ReputationScore
): { isDegrading: boolean; changes: string[] } {
  const changes: string[] = [];

  if (currentScore.score < previousScore.score) {
    changes.push(`Score decreased from ${previousScore.score} to ${currentScore.score}`);
  }

  if (currentScore.metrics.bounceRate > previousScore.metrics.bounceRate) {
    changes.push(
      `Bounce rate increased from ${previousScore.metrics.bounceRate.toFixed(2)}% to ${currentScore.metrics.bounceRate.toFixed(2)}%`
    );
  }

  if (currentScore.metrics.complaintRate > previousScore.metrics.complaintRate) {
    changes.push(
      `Complaint rate increased from ${previousScore.metrics.complaintRate.toFixed(3)}% to ${currentScore.metrics.complaintRate.toFixed(3)}%`
    );
  }

  if (
    currentScore.metrics.blacklistStatus === 'listed' &&
    previousScore.metrics.blacklistStatus !== 'listed'
  ) {
    changes.push('Domain newly listed on blacklist');
  }

  return {
    isDegrading: changes.length > 0,
    changes,
  };
}

/**
 * Get reputation grade color
 */
export function getReputationGradeColor(grade: string): string {
  switch (grade) {
    case 'A':
      return 'text-green-400';
    case 'B':
      return 'text-lime-400';
    case 'C':
      return 'text-yellow-400';
    case 'D':
      return 'text-orange-400';
    case 'F':
      return 'text-red-400';
    default:
      return 'text-gray-400';
  }
}

/**
 * Get reputation status color
 */
export function getReputationStatusColor(status: string): string {
  switch (status) {
    case 'excellent':
      return 'bg-green-600 text-white';
    case 'good':
      return 'bg-lime-600 text-white';
    case 'fair':
      return 'bg-yellow-600 text-white';
    case 'poor':
      return 'bg-orange-600 text-white';
    case 'critical':
      return 'bg-red-600 text-white';
    default:
      return 'bg-gray-600 text-white';
  }
}
