/**
 * Centralized error handling utilities
 */

import {
  AppError,
  NetworkError,
  ValidationError,
  AuthenticationError,
  AuthorizationError,
  NotFoundError,
  ServerError,
} from './types/errors'

/**
 * Convert an unknown error to an AppError
 */
export function normalizeError(error: unknown): AppError {
  if (error instanceof AppError) {
    return error
  }

  if (error instanceof Error) {
    // Check for network errors
    if (error.message.includes('fetch') || error.message.includes('network')) {
      return new NetworkError(error.message, error)
    }

    return new ServerError(error.message, error)
  }

  if (typeof error === 'string') {
    return new ServerError(error)
  }

  return new ServerError('An unknown error occurred')
}

/**
 * Handle API errors
 */
export function handleApiError(error: unknown): AppError {
  const normalized = normalizeError(error)

  // Log error for monitoring
  if (typeof window !== 'undefined') {
    console.error('API Error:', normalized)
    // TODO: Send to error tracking service
  }

  return normalized
}

/**
 * Get user-friendly error message
 */
export function getUserFriendlyMessage(error: AppError): string {
  switch (error.code) {
    case 'NETWORK_ERROR':
      return 'Unable to connect to the server. Please check your internet connection and try again.'
    case 'VALIDATION_ERROR':
      return error.message || 'Please check your input and try again.'
    case 'AUTH_ERROR':
      return 'Your session has expired. Please log in again.'
    case 'AUTHZ_ERROR':
      return 'You do not have permission to perform this action.'
    case 'NOT_FOUND':
      return 'The requested resource was not found.'
    case 'SERVER_ERROR':
      return 'An error occurred on the server. Please try again later.'
    default:
      return error.message || 'An unexpected error occurred. Please try again.'
  }
}

/**
 * Check if error is retryable
 */
export function isRetryableError(error: AppError): boolean {
  return (
    error.code === 'NETWORK_ERROR' ||
    (error.statusCode !== undefined && error.statusCode >= 500 && error.statusCode < 600)
  )
}

/**
 * Get retry delay in milliseconds
 */
export function getRetryDelay(attempt: number, baseDelay = 1000): number {
  return Math.min(baseDelay * Math.pow(2, attempt), 30000) // Max 30 seconds
}

