/**
 * User-Friendly Error Messages
 *
 * Common error pattern matchers and message generators that can be composed
 * with domain-specific error handlers.
 *
 * Usage:
 * - Use `matchCommonError()` for generic network/timeout/auth errors
 * - Use domain-specific handlers for business logic errors
 * - Compose both for complete error handling
 */

/**
 * Common error pattern result
 */
export interface ErrorMatchResult {
  matched: boolean;
  message: string;
}

/**
 * Error pattern category for context-aware messages
 */
export type ErrorCategory = "generic" | "sim" | "payment" | "billing" | "support";

/**
 * Check if error message matches a timeout pattern
 */
export function isTimeoutError(message: string): boolean {
  const lowerMessage = message.toLowerCase();
  return lowerMessage.includes("timeout") || lowerMessage.includes("timed out");
}

/**
 * Check if error message matches a network/connection pattern
 */
export function isNetworkError(message: string): boolean {
  const lowerMessage = message.toLowerCase();
  return (
    lowerMessage.includes("network") ||
    lowerMessage.includes("connection") ||
    lowerMessage.includes("econnrefused") ||
    lowerMessage.includes("econnreset") ||
    lowerMessage.includes("socket hang up") ||
    lowerMessage.includes("fetch failed")
  );
}

/**
 * Check if error message matches an authentication pattern
 */
export function isAuthError(message: string): boolean {
  const lowerMessage = message.toLowerCase();
  return (
    lowerMessage.includes("unauthorized") ||
    lowerMessage.includes("forbidden") ||
    lowerMessage.includes("authentication failed") ||
    lowerMessage.includes("403") ||
    lowerMessage.includes("401")
  );
}

/**
 * Check if error message matches a rate limit pattern
 */
export function isRateLimitError(message: string): boolean {
  const lowerMessage = message.toLowerCase();
  return (
    lowerMessage.includes("rate limit") ||
    lowerMessage.includes("too many requests") ||
    lowerMessage.includes("429")
  );
}

/**
 * Check if error message matches a permission error
 */
export function isPermissionError(message: string): boolean {
  const lowerMessage = message.toLowerCase();
  return lowerMessage.includes("invalid permissions") || lowerMessage.includes("not allowed");
}

/**
 * Get context-aware message for timeout errors
 */
export function getTimeoutMessage(category: ErrorCategory = "generic"): string {
  switch (category) {
    case "sim":
      return "SIM service request timed out. Please try again.";
    case "payment":
      return "Payment processing timed out. Please try again.";
    default:
      return "The request timed out. Please try again.";
  }
}

/**
 * Get context-aware message for network errors
 */
export function getNetworkMessage(category: ErrorCategory = "generic"): string {
  switch (category) {
    case "sim":
      return "SIM service request timed out. Please try again.";
    case "payment":
      return "Payment processing timed out. Please try again.";
    default:
      return "Network error. Please check your connection and try again.";
  }
}

/**
 * Get context-aware message for auth errors
 */
export function getAuthMessage(category: ErrorCategory = "generic"): string {
  switch (category) {
    case "sim":
      return "SIM service is temporarily unavailable. Please try again later.";
    case "payment":
      return "Payment processing is temporarily unavailable. Please contact support for assistance.";
    default:
      return "Service is temporarily unavailable. Please try again later.";
  }
}

/**
 * Get context-aware message for rate limit errors
 */
export function getRateLimitMessage(category: ErrorCategory = "generic"): string {
  switch (category) {
    case "sim":
      return "SIM service is busy. Please wait a moment and try again.";
    case "payment":
      return "Payment service is busy. Please wait a moment and try again.";
    default:
      return "Service is busy. Please wait a moment and try again.";
  }
}

/**
 * Get context-aware message for permission errors
 */
export function getPermissionMessage(category: ErrorCategory = "generic"): string {
  switch (category) {
    case "sim":
      return "SIM service is temporarily unavailable. Please contact support for assistance.";
    case "payment":
      return "Payment processing is temporarily unavailable. Please contact support for assistance.";
    default:
      return "This operation is temporarily unavailable. Please contact support for assistance.";
  }
}

/**
 * Get default fallback message for category
 */
export function getDefaultMessage(category: ErrorCategory = "generic"): string {
  switch (category) {
    case "sim":
      return "SIM operation failed. Please try again or contact support.";
    case "payment":
      return "Unable to process payment. Please try again or contact support.";
    case "billing":
      return "Billing operation failed. Please try again or contact support.";
    case "support":
      return "Unable to complete request. Please try again or contact support.";
    default:
      return "An unexpected error occurred. Please try again later.";
  }
}

/**
 * Match common error patterns and return appropriate user-friendly message.
 *
 * @param errorMessage - The technical error message to match
 * @param category - Context category for appropriate messaging
 * @returns Match result with whether pattern matched and the message
 *
 * @example
 * const result = matchCommonError(error.message, "sim");
 * if (result.matched) {
 *   return result.message;
 * }
 * // Fall through to domain-specific error handling
 */
export function matchCommonError(
  errorMessage: string,
  category: ErrorCategory = "generic"
): ErrorMatchResult {
  if (!errorMessage) {
    return { matched: false, message: getDefaultMessage(category) };
  }

  // Check patterns in order of specificity
  if (isRateLimitError(errorMessage)) {
    return { matched: true, message: getRateLimitMessage(category) };
  }

  if (isAuthError(errorMessage)) {
    return { matched: true, message: getAuthMessage(category) };
  }

  if (isPermissionError(errorMessage)) {
    return { matched: true, message: getPermissionMessage(category) };
  }

  if (isTimeoutError(errorMessage)) {
    return { matched: true, message: getTimeoutMessage(category) };
  }

  if (isNetworkError(errorMessage)) {
    return { matched: true, message: getNetworkMessage(category) };
  }

  return { matched: false, message: getDefaultMessage(category) };
}

/**
 * Get user-friendly message for any error, with fallback to default.
 *
 * This is a convenience function that always returns a user-friendly message.
 * Use this when you don't need to check if a common pattern matched.
 *
 * @example
 * return getUserFriendlyMessage(error.message, "payment");
 */
export function getUserFriendlyMessage(
  errorMessage: string,
  category: ErrorCategory = "generic"
): string {
  const result = matchCommonError(errorMessage, category);
  return result.message;
}
