import { ApiResponse } from "@/types/api-response";

/**
 * Custom error class for API errors with extracted message
 * Re-exported from create-api-client for convenience
 */
export { ApiError } from "@/lib/api/create-api-client";

/**
 * API Error item structure from backend errors array
 */
export interface ApiErrorItem {
  message: string;
  members?: string[];
}

/**
 * Extracts a user-friendly error message from API response.
 * Prioritizes `errors` array messages, falls back to `message` field.
 *
 * @param response - The API response object
 * @param fallbackMessage - Default message if no error info available
 * @returns A formatted error message string
 */
export function extractApiErrorMessage(
  response: Partial<ApiResponse> | null | undefined,
  fallbackMessage = "Bir hata oluştu. Lütfen tekrar deneyin.",
): string {
  if (!response) {
    return fallbackMessage;
  }

  // Check if errors array exists and has items
  if (
    response.errors &&
    Array.isArray(response.errors) &&
    response.errors.length > 0
  ) {
    // Extract messages from errors array
    const errorMessages = response.errors
      .map((error: ApiErrorItem | string) => {
        if (typeof error === "string") {
          return error;
        }
        return error?.message || "";
      })
      .filter((msg) => msg.length > 0);

    if (errorMessages.length > 0) {
      return errorMessages.join("\n");
    }
  }

  // Fallback to message field
  if (response.message && response.message.length > 0) {
    return response.message;
  }

  return fallbackMessage;
}

/**
 * Extracts error messages as an array from API response.
 * Useful when you need to display multiple errors separately.
 *
 * @param response - The API response object
 * @param fallbackMessage - Default message if no error info available
 * @returns An array of error message strings
 */
export function extractApiErrorMessages(
  response: Partial<ApiResponse> | null | undefined,
  fallbackMessage = "Bir hata oluştu. Lütfen tekrar deneyin.",
): string[] {
  if (!response) {
    return [fallbackMessage];
  }

  // Check if errors array exists and has items
  if (
    response.errors &&
    Array.isArray(response.errors) &&
    response.errors.length > 0
  ) {
    const errorMessages = response.errors
      .map((error: ApiErrorItem | string) => {
        if (typeof error === "string") {
          return error;
        }
        return error?.message || "";
      })
      .filter((msg) => msg.length > 0);

    if (errorMessages.length > 0) {
      return errorMessages;
    }
  }

  // Fallback to message field
  if (response.message && response.message.length > 0) {
    return [response.message];
  }

  return [fallbackMessage];
}

/**
 * Checks if an API response represents a validation error (422)
 */
export function isValidationError(
  response: Partial<ApiResponse> | null | undefined,
): boolean {
  return response?.status === 422;
}

/**
 * Gets field-specific error messages from API validation errors
 * Returns a map of field names to their error messages
 */
export function getFieldErrors(
  response: Partial<ApiResponse> | null | undefined,
): Record<string, string[]> {
  const fieldErrors: Record<string, string[]> = {};

  if (!response?.errors || !Array.isArray(response.errors)) {
    return fieldErrors;
  }

  response.errors.forEach((error: ApiErrorItem) => {
    if (error.members && Array.isArray(error.members)) {
      error.members.forEach((fieldName: string) => {
        if (!fieldErrors[fieldName]) {
          fieldErrors[fieldName] = [];
        }
        if (error.message) {
          fieldErrors[fieldName].push(error.message);
        }
      });
    }
  });

  return fieldErrors;
}
