/**
 * Standard API response wrapper for type-safe API responses
 *
 * This type provides a consistent structure for all API responses:
 * - success: boolean indicating if the request was successful
 * - data: The actual response data (present when success is true)
 * - error: Error message (present when success is false)
 * - message: Optional message (can be used for success or error messages)
 * - code: Optional error code for programmatic error handling
 * - statusCode: Optional HTTP status code
 */
export interface ApiResponse<T = unknown> {
  success: boolean
  data?: T
  error?: string
  message?: string
  code?: string
  statusCode?: number
}

/**
 * Type guard to check if an ApiResponse is successful
 */
export function isSuccessResponse<T>(response: ApiResponse<T>): response is ApiResponse<T> & { success: true, data: T } {
  return response.success === true && response.data !== undefined
}

/**
 * Type guard to check if an ApiResponse is an error
 */
export function isErrorResponse<T>(response: ApiResponse<T>): response is ApiResponse<T> & { success: false, error: string } {
  return response.success === false
}

/**
 * Extract data from ApiResponse, throwing if it's an error response
 *
 * @example
 * const response = await apiCall<User>('/api/user/profile')
 * const user = extractData(response) // Type is User, throws if error
 */
export function extractData<T>(response: ApiResponse<T>): T {
  if (!isSuccessResponse(response)) {
    throw new Error(response.error || 'API request failed')
  }
  return response.data
}

/**
 * Extract data from ApiResponse, returning null if it's an error response
 *
 * @example
 * const response = await apiCall<User>('/api/user/profile')
 * const user = extractDataOrNull(response) // Type is T | null
 */
export function extractDataOrNull<T>(response: ApiResponse<T>): T | null {
  return isSuccessResponse(response) ? response.data : null
}

/**
 * Create a success ApiResponse
 */
export function createSuccessResponse<T>(data: T, message?: string): ApiResponse<T> {
  return {
    success: true,
    data,
    ...(message && { message })
  }
}

/**
 * Create an error ApiResponse
 */
export function createErrorResponse(error: string, code?: string, statusCode?: number): ApiResponse<never> {
  return {
    success: false,
    error,
    ...(code && { code }),
    ...(statusCode && { statusCode })
  }
}
