/**
 * ============================================
 * ERROR TYPES
 * ============================================
 * 
 * Error types and classes
 * Primarily used by backend, but shared for type consistency
 */

// Extend ErrorConstructor for Node.js captureStackTrace
declare global {
  interface ErrorConstructor {
    captureStackTrace?(targetObject: object, constructorOpt?: Function): void;
  }
}

// ============================================
// ERROR CODES
// ============================================

export type ErrorCode = 
  | 'INTERNAL_ERROR'
  | 'VALIDATION_ERROR'
  | 'AUTHENTICATION_ERROR'
  | 'AUTHORIZATION_ERROR'
  | 'NOT_FOUND'
  | 'CONFLICT_ERROR'
  | 'RATE_LIMIT_ERROR'
  | 'BAD_REQUEST'
  | 'SERVICE_UNAVAILABLE';

// ============================================
// APP ERROR INTERFACE
// ============================================

export interface AppError extends Error {
  code: ErrorCode;
  statusCode: number;
  isOperational: boolean;
  details?: unknown;
}

// ============================================
// ERROR CLASSES (Backend usage)
// ============================================

export class ApplicationError extends Error implements AppError {
  code: ErrorCode;
  statusCode: number;
  isOperational: boolean;
  details?: unknown;

  constructor(
    message: string,
    code: ErrorCode = 'INTERNAL_ERROR',
    statusCode: number = 500,
    isOperational: boolean = true,
    details?: unknown
  ) {
    super(message);
    this.name = 'ApplicationError';
    this.code = code;
    this.statusCode = statusCode;
    this.isOperational = isOperational;
    this.details = details;
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, this.constructor);
    }
  }
}

export class ValidationError extends ApplicationError {
  constructor(message: string, details?: unknown) {
    super(message, 'VALIDATION_ERROR', 400, true, details);
    this.name = 'ValidationError';
  }
}

export class AuthenticationError extends ApplicationError {
  constructor(message: string = 'Authentication failed') {
    super(message, 'AUTHENTICATION_ERROR', 401, true);
    this.name = 'AuthenticationError';
  }
}

export class AuthorizationError extends ApplicationError {
  constructor(message: string = 'Insufficient permissions') {
    super(message, 'AUTHORIZATION_ERROR', 403, true);
    this.name = 'AuthorizationError';
  }
}

export class NotFoundError extends ApplicationError {
  constructor(resource: string) {
    super(`${resource} not found`, 'NOT_FOUND', 404, true);
    this.name = 'NotFoundError';
  }
}

export class ConflictError extends ApplicationError {
  constructor(message: string, details?: unknown) {
    super(message, 'CONFLICT_ERROR', 409, true, details);
    this.name = 'ConflictError';
  }
}

export class RateLimitError extends ApplicationError {
  constructor(retryAfter?: number) {
    super(
      'Too many requests',
      'RATE_LIMIT_ERROR',
      429,
      true,
      { retryAfter }
    );
    this.name = 'RateLimitError';
  }
}
