/**
 * DashCaddy API Error Classes
 * All errors inherit from AppError and provide consistent structure.
 */

class AppError extends Error {
  constructor(message, statusCode = 500, code = null) {
    super(message);
    this.name = this.constructor.name;
    this.statusCode = statusCode;
    this.code = code || this.constructor.name.toUpperCase().replace(/ERROR$/, '_ERROR');
    this.isOperational = true; // Distinguishes from programming errors
  }
}

// 4xx Client Errors

class ValidationError extends AppError {
  constructor(message, field = null) {
    super(message, 400, 'DC-400');
    this.field = field;
  }
}

class AuthenticationError extends AppError {
  constructor(message = 'Authentication required', requiresTotp = false) {
    super(message, 401, 'DC-401');
    this.requiresTotp = requiresTotp;
  }
}

class ForbiddenError extends AppError {
  constructor(message = 'Forbidden') {
    super(message, 403, 'DC-403');
  }
}

class NotFoundError extends AppError {
  constructor(resource = 'Resource') {
    super(`${resource} not found`, 404, 'DC-404');
    this.resource = resource;
  }
}

class ConflictError extends AppError {
  constructor(message, conflictingResource = null) {
    super(message, 409, 'DC-409');
    this.conflictingResource = conflictingResource;
  }
}

class RateLimitError extends AppError {
  constructor(retryAfter = 60) {
    super('Rate limit exceeded', 429, 'DC-429');
    this.retryAfter = retryAfter;
  }
}

// 5xx Server Errors

class DockerError extends AppError {
  constructor(message, operation = null, details = {}) {
    super(message, 500, 'DC-500-DOCKER');
    this.operation = operation;
    this.details = details;
  }
}

class CaddyError extends AppError {
  constructor(message, operation = null, details = {}) {
    super(message, 502, 'DC-502-CADDY');
    this.operation = operation;
    this.details = details;
  }
}

class DNSError extends AppError {
  constructor(message, operation = null, details = {}) {
    super(message, 502, 'DC-502-DNS');
    this.operation = operation;
    this.details = details;
  }
}

class ServiceUnavailableError extends AppError {
  constructor(service, retryAfter = null) {
    super(`Service unavailable: ${service}`, 503, 'DC-503');
    this.service = service;
    this.retryAfter = retryAfter;
  }
}

module.exports = {
  AppError,
  ValidationError,
  AuthenticationError,
  ForbiddenError,
  NotFoundError,
  ConflictError,
  RateLimitError,
  DockerError,
  CaddyError,
  DNSError,
  ServiceUnavailableError
};
