/**
 * Response Helper Functions
 * 
 * Utility functions for safely handling API responses
 */

import { isSuccessResponse, isErrorResponse } from './types.ts';
import type { APIResponse, SuccessResponse, ErrorResponse } from './types.ts';

/**
 * Safely extract data from an API response
 * Returns the data if successful, or null if error
 */
export function safeExtractData<T, M>(response: APIResponse<T, M>): T | null {
  if (isSuccessResponse(response)) {
    return response.data;
  }
  return null;
}

/**
 * Safely extract metadata from an API response
 * Returns the metadata if successful, or null if error
 */
export function safeExtractMetadata<T, M>(response: APIResponse<T, M>): M | null {
  if (isSuccessResponse(response)) {
    return response.metadata ?? null;
  }
  return null;
}

/**
 * Get error details from a response
 * Returns error details if it's an error response, null otherwise
 */
export function getErrorDetails(response: APIResponse): ErrorResponse['problem'] | null {
  if (isErrorResponse(response)) {
    return response.problem;
  }
  return null;
}

/**
 * Check if response indicates success
 */
export function isSuccess<T, M>(response: APIResponse<T, M>): response is SuccessResponse<T, M> {
  return isSuccessResponse(response);
}

/**
 * Check if response indicates error
 */
export function isError(response: APIResponse): response is ErrorResponse {
  return isErrorResponse(response);
}

/**
 * Transform response data safely
 * Applies transform function only if response is successful
 */
export function transformResponseData<T, R, M>(
  response: APIResponse<T, M>,
  transform: (data: T) => R
): APIResponse<R, M> {
  if (isSuccessResponse(response)) {
    try {
      const transformedData = transform(response.data);
      return {
        success: true,
        data: transformedData,
        metadata: response.metadata
      };
    } catch (error) {
      // Transform failed, return error response
      return {
        success: false,
        problem: {
          status: 500,
          type: 'transformation-error',
          title: 'Data Transformation Failed',
          detail: error instanceof Error ? error.message : 'Unknown transformation error',
          instance: '/client/transform',
          context: {
            request: 'Data transformation',
            responseText: 'Transform function threw an error'
          },
          issues: []
        }
      };
    }
  }
  // Return original error response
  return response as ErrorResponse;
}

/**
 * Combine multiple responses into a single result
 * All responses must be successful for the result to be successful
 */
export function combineResponses<T1, T2, M1, M2>(
  response1: APIResponse<T1, M1>,
  response2: APIResponse<T2, M2>
): APIResponse<{ first: T1; second: T2 }, { first: M1; second: M2 }> {
  if (isSuccessResponse(response1) && isSuccessResponse(response2)) {
    return {
      success: true,
      data: {
        first: response1.data,
        second: response2.data
      },
      metadata: {
        first: response1.metadata ?? ({} as M1),
        second: response2.metadata ?? ({} as M2)
      }
    };
  }

  // Return the first error found, or create a combined error
  const firstError = isErrorResponse(response1) ? response1.problem : null;
  const secondError = isErrorResponse(response2) ? response2.problem : null;

  if (firstError && secondError) {
    return {
      success: false,
      problem: {
        status: 400,
        type: 'multiple-errors',
        title: 'Multiple Request Failures',
        detail: 'One or more requests failed',
        instance: '/client/combine',
        context: {
          request: 'Combined requests',
          responseText: 'Multiple failures occurred'
        },
        issues: [
          `First: ${firstError.title} - ${firstError.detail}`,
          `Second: ${secondError.title} - ${secondError.detail}`
        ]
      }
    };
  }

  return (firstError ? response1 : response2) as ErrorResponse;
}