/**
 * Enhanced fetch wrapper with proxy support and automatic debug logging
 * Drop-in replacement for native fetch with additional features
 */

export interface BunRequestInit extends RequestInit {
  proxy?: string;
}

export interface FetchOptions extends RequestInit {
  logger?: any;
  proxy?: string | null;
  timeout?: number;
}

export async function fetch(input: RequestInfo | URL, options?: FetchOptions): Promise<Response> {
  const logger = options?.logger || console;
  const url =
    typeof input === 'string' ? input : input instanceof URL ? input.href : (input as Request).url;

  // Build request options
  const requestOptions: RequestInit = {
    method: options?.method || 'GET',
    headers: options?.headers || {},
    body: options?.body,
    signal: options?.signal,
    credentials: options?.credentials,
    cache: options?.cache,
    redirect: options?.redirect,
    referrer: options?.referrer,
    referrerPolicy: options?.referrerPolicy,
    integrity: options?.integrity,
    keepalive: options?.keepalive,
    mode: options?.mode,
  };
  // Handle proxy for Bun
  if (options?.proxy) {
    // Bun supports proxy via fetch options
    (requestOptions as BunRequestInit).proxy = options.proxy;
  }

  // Handle timeout
  if (options?.timeout) {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), options.timeout);
    requestOptions.signal = controller.signal;

    try {
      const response = await performFetch(input, requestOptions, logger, url);
      clearTimeout(timeoutId);
      return response;
    } catch (error) {
      clearTimeout(timeoutId);
      throw error;
    }
  }

  return performFetch(input, requestOptions, logger, url);
}

async function performFetch(
  input: RequestInfo | URL,
  requestOptions: RequestInit,
  logger: any,
  url: string
): Promise<Response> {
  logger.debug('HTTP request', {
    method: requestOptions.method,
    url,
    headers: requestOptions.headers,
    proxy: (requestOptions as BunRequestInit).proxy || null,
  });

  try {
    const response = await globalThis.fetch(input, requestOptions);

    logger.debug('HTTP response', {
      url,
      status: response.status,
      statusText: response.statusText,
      ok: response.ok,
      headers: Object.fromEntries(response.headers.entries()),
    });

    return response;
  } catch (error) {
    logger.debug('HTTP error', {
      url,
      error: error instanceof Error ? error.message : String(error),
      name: error instanceof Error ? error.name : 'Unknown',
    });
    throw error;
  }
}
