import { IAPIErrorResponse } from "../types/common";

/**
 * Known backend error/validation codes mapped to human-readable messages.
 * Backend often returns SCREAMING_SNAKE_CASE codes (e.g. in `message` or the
 * field-level `errors` object); these should never be shown to users verbatim.
 */
const ERROR_MESSAGES: Record<string, string> = {
  ERROR_WHILE_VALIDATING_REQUEST:
    "Please check the details you entered and try again.",
  FORGOT_PASSWORD_EMAIL_MUST_BE_VALID_EMAIL:
    "Please enter a valid email address.",
};

/**
 * Fallback for unmapped codes: turn SCREAMING_SNAKE_CASE into a readable
 * sentence so users never see a raw code. Non-code strings are returned as-is.
 */
const humanizeCode = (value: string): string => {
  if (!/^[A-Z0-9]+(?:_[A-Z0-9]+)+$/.test(value)) return value;
  const sentence = value.toLowerCase().replace(/_/g, " ").trim();
  return sentence.charAt(0).toUpperCase() + sentence.slice(1);
};

const translate = (value?: string | null): string =>
  value ? ERROR_MESSAGES[value] ?? humanizeCode(value) : "";

/**
 * Reusable utility to parse backend API errors into a human-readable string.
 * Supports both generic messages and nested 'errors' objects for field-level
 * validation, translating known codes into friendly messages.
 */
export const parseApiError = (error: any): string => {
  // Handle success-shaped response with message
  if (error?.message && !error?.data) {
    return translate(error.message);
  }

  const apiError = error as IAPIErrorResponse;
  const fieldErrors = apiError.data?.errors;

  // If we have specific field-level validation errors, surface their (translated)
  // messages — one per line — without the raw code or field prefix.
  if (
    fieldErrors &&
    typeof fieldErrors === "object" &&
    Object.keys(fieldErrors).length > 0
  ) {
    const messages = Object.values(fieldErrors).map((msg) =>
      translate(String(msg)),
    );
    return messages.join("\n");
  }

  // Fallback to the top-level message or a generic error string
  return (
    translate(apiError.data?.message) ||
    translate(error?.message) ||
    "An unexpected error occurred. Please try again."
  );
};
