import { describe, it, expect } from 'vitest';
import {
  scoreEmailDeliverability,
  scoreEmailBatch,
  getAverageDeliverabilityScore,
  filterByRiskLevel,
  calculateSenderReputation,
  generateDeliverabilityReport,
} from './_core/deliverabilityScoring.ts';

describe('Email Deliverability Scoring', () => {
  it('should score valid email with high score', () => {
    const score = scoreEmailDeliverability('john.doe@example.com');

    expect(score.email).toBe('john.doe@example.com');
    expect(score.score).toBeGreaterThanOrEqual(70);
    expect(['low', 'medium']).toContain(score.riskLevel);
  });

  it('should flag invalid email format', () => {
    const score = scoreEmailDeliverability('invalid-email');

    expect(score.score).toBeLessThanOrEqual(50);
    expect(['high', 'critical']).toContain(score.riskLevel);
    expect(score.issues.length).toBeGreaterThan(0);
  });

  it('should flag disposable email addresses', () => {
    const score = scoreEmailDeliverability('user@tempmail.com');

    expect(score.score).toBeLessThanOrEqual(80);
    expect(score.warnings.length).toBeGreaterThan(0);
    expect(score.warnings[0]).toContain('Disposable');
  });

  it('should flag role-based email addresses', () => {
    const score = scoreEmailDeliverability('info@example.com');

    expect(score.warnings.length).toBeGreaterThan(0);
    expect(score.warnings[0]).toContain('Role-based');
  });

  it('should score batch of emails', () => {
    const emails = [
      'john@example.com',
      'jane@example.com',
      'invalid-email',
    ];

    const scores = scoreEmailBatch(emails);

    expect(scores.length).toBe(3);
    expect(scores[0].score).toBeGreaterThan(scores[2].score);
  });

  it('should calculate average deliverability score', () => {
    const emails = ['john@example.com', 'jane@example.com', 'bob@example.com'];
    const scores = scoreEmailBatch(emails);

    const average = getAverageDeliverabilityScore(scores);

    expect(average).toBeGreaterThanOrEqual(0);
    expect(average).toBeLessThanOrEqual(100);
  });

  it('should filter emails by risk level', () => {
    const emails = [
      'john@example.com',
      'invalid-email',
      'jane@example.com',
    ];
    const scores = scoreEmailBatch(emails);

    const lowRisk = filterByRiskLevel(scores, 'low');
    const highRisk = filterByRiskLevel(scores, 'high');
    const critical = filterByRiskLevel(scores, 'critical');

    expect(lowRisk.length + highRisk.length + critical.length).toBeGreaterThan(0);
    expect(scores.length).toBe(3);
  });

  it('should calculate sender reputation', () => {
    const reputation = calculateSenderReputation('example.com', {
      bounceRate: 2,
      complaintRate: 0.05,
      unsubscribeRate: 0.2,
      spfConfigured: true,
      dkimConfigured: true,
      dmarcConfigured: true,
      isBlacklisted: false,
    });

    expect(reputation.domain).toBe('example.com');
    expect(reputation.reputationScore).toBeGreaterThan(50);
    expect(reputation.spfRecord).toBe(true);
    expect(reputation.blacklistStatus).toBe('clean');
  });

  it('should penalize blacklisted domains', () => {
    const reputation = calculateSenderReputation('spam.com', {
      bounceRate: 5,
      complaintRate: 0.1,
      unsubscribeRate: 0.5,
      spfConfigured: false,
      dkimConfigured: false,
      dmarcConfigured: false,
      isBlacklisted: true,
    });

    expect(reputation.reputationScore).toBeLessThanOrEqual(50);
    expect(reputation.blacklistStatus).toBe('listed');
  });

  it('should generate deliverability report', () => {
    const emails = [
      'john@example.com',
      'jane@example.com',
      'invalid-email',
      'user@tempmail.com',
    ];
    const scores = scoreEmailBatch(emails);

    const report = generateDeliverabilityReport(scores);

    expect(report.totalEmails).toBe(4);
    expect(report.averageScore).toBeGreaterThan(0);
    expect(report.riskBreakdown.low).toBeGreaterThan(0);
    expect(report.riskBreakdown.high + report.riskBreakdown.critical).toBeGreaterThan(0);
  });

  it('should handle empty email batch', () => {
    const scores = scoreEmailBatch([]);
    const average = getAverageDeliverabilityScore(scores);

    expect(scores.length).toBe(0);
    expect(average).toBe(0);
  });

  it('should provide recommendations for risky emails', () => {
    const score = scoreEmailDeliverability('user@tempmail.com');

    expect(score.warnings.length + score.recommendations.length).toBeGreaterThan(0);
  });
});
