/**
 * Custom error classes for email service
 */

export class EmailServiceError extends Error {
  public code: string;
  public details?: any;
  public timestamp: Date;

  constructor(message: string, code: string, details?: any) {
    super(message);
    this.name = 'EmailServiceError';
    this.code = code;
    this.details = details;
    this.timestamp = new Date();
  }
}

export class ConfigurationError extends EmailServiceError {
  constructor(message: string, details?: any) {
    super(message, 'CONFIG_ERROR', details);
    this.name = 'ConfigurationError';
  }
}

export class ProviderError extends EmailServiceError {
  public provider: string;

  constructor(message: string, provider: string, details?: any) {
    super(message, 'PROVIDER_ERROR', details);
    this.name = 'ProviderError';
    this.provider = provider;
  }
}

export class ValidationError extends EmailServiceError {
  constructor(message: string, details?: any) {
    super(message, 'VALIDATION_ERROR', details);
    this.name = 'ValidationError';
  }
}

export class TemplateError extends EmailServiceError {
  constructor(message: string, details?: any) {
    super(message, 'TEMPLATE_ERROR', details);
    this.name = 'TemplateError';
  }
}

export class RetryError extends EmailServiceError {
  public retryCount: number;
  public maxRetries: number;

  constructor(message: string, retryCount: number, maxRetries: number, details?: any) {
    super(message, 'RETRY_ERROR', details);
    this.name = 'RetryError';
    this.retryCount = retryCount;
    this.maxRetries = maxRetries;
  }
}

export class TimeoutError extends EmailServiceError {
  public timeoutMs: number;

  constructor(message: string, timeoutMs: number, details?: any) {
    super(message, 'TIMEOUT_ERROR', details);
    this.name = 'TimeoutError';
    this.timeoutMs = timeoutMs;
  }
}

export class RateLimitError extends EmailServiceError {
  public retryAfter: number | undefined;

  constructor(message: string, retryAfter?: number, details?: any) {
    super(message, 'RATE_LIMIT_ERROR', details);
    this.name = 'RateLimitError';
    this.retryAfter = retryAfter;
  }
}

export class AuthenticationError extends EmailServiceError {
  constructor(message: string, details?: any) {
    super(message, 'AUTH_ERROR', details);
    this.name = 'AuthenticationError';
  }
}

export class NetworkError extends EmailServiceError {
  public statusCode: number | undefined;

  constructor(message: string, statusCode?: number, details?: any) {
    super(message, 'NETWORK_ERROR', details);
    this.name = 'NetworkError';
    this.statusCode = statusCode;
  }
}

export class InvalidEmailError extends ValidationError {
  constructor(email: string, details?: any) {
    super(`Invalid email address: ${email}`, details);
    this.name = 'InvalidEmailError';
  }
}

export class MissingRequiredFieldError extends ValidationError {
  constructor(field: string, details?: any) {
    super(`Missing required field: ${field}`, details);
    this.name = 'MissingRequiredFieldError';
  }
}

export class InvalidTemplateError extends TemplateError {
  constructor(template: string, details?: any) {
    super(`Invalid template: ${template}`, details);
    this.name = 'InvalidTemplateError';
  }
}

export class TemplateNotFoundError extends TemplateError {
  constructor(template: string, details?: any) {
    super(`Template not found: ${template}`, details);
    this.name = 'TemplateNotFoundError';
  }
}

export class ConnectionError extends EmailServiceError {
  public provider: string;

  constructor(message: string, provider: string, details?: any) {
    super(message, 'CONNECTION_ERROR', details);
    this.name = 'ConnectionError';
    this.provider = provider;
  }
}

export class QuotaExceededError extends EmailServiceError {
  public quota: string;
  public limit: number;
  public used: number;

  constructor(message: string, quota: string, limit: number, used: number, details?: any) {
    super(message, 'QUOTA_EXCEEDED_ERROR', details);
    this.name = 'QuotaExceededError';
    this.quota = quota;
    this.limit = limit;
    this.used = used;
  }
}

export class SpamDetectionError extends EmailServiceError {
  public reason: string;

  constructor(message: string, reason: string, details?: any) {
    super(message, 'SPAM_DETECTION_ERROR', details);
    this.name = 'SpamDetectionError';
    this.reason = reason;
  }
}
