import { apiErrorResponseSchema, type ApiErrorResponse } from "@customer-portal/domain/common";

/**
 * API Response Helper Types and Functions
 *
 * Generic utilities for working with API responses.
 *
 * Note: Success responses from the BFF return data directly (no `{ success: true, data }` envelope).
 * Error responses are returned as `{ success: false, error: { code, message, details? } }` and
 * are surfaced via the API client error handler.
 */

/**
 * Generic API response wrapper from the client.
 * After client unwrapping, `data` contains the actual payload (not the BFF envelope).
 */
export type ApiResponse<T> = {
  data?: T;
  error?: unknown;
};

/**
 * Extract data from API response or return null.
 * Useful for optional data handling.
 */
export function getNullableData<T>(response: ApiResponse<T>): T | null {
  if (response.error || response.data === undefined) {
    return null;
  }
  return response.data;
}

/**
 * Extract data from API response or throw error.
 */
export function getDataOrThrow<T>(response: ApiResponse<T>, errorMessage?: string): T {
  if (response.error || response.data === undefined) {
    throw new Error(errorMessage || "Failed to fetch data");
  }
  return response.data;
}

/**
 * Extract data from API response or return default value.
 */
export function getDataOrDefault<T>(response: ApiResponse<T>, defaultValue: T): T {
  return response.data ?? defaultValue;
}

/**
 * Check if response has an error.
 */
export function hasError<T>(response: ApiResponse<T>): boolean {
  return !!response.error;
}

/**
 * Check if response has data.
 */
export function hasData<T>(response: ApiResponse<T>): boolean {
  return response.data !== undefined && !response.error;
}

/**
 * Parse an error payload into a structured API error response.
 */
export function parseDomainError(payload: unknown): ApiErrorResponse | null {
  const parsed = apiErrorResponseSchema.safeParse(payload);
  return parsed.success ? parsed.data : null;
}
