import WebSocket from 'isomorphic-ws';

/**
 * If the connection is not established within the timeout, the promise will be rejected.
 * This can happen with bad network conditions, but is very rare.
 */
export function connectWebSocket(wsUrl: string, protocol?: string | string[], timeout = 30_000): Promise<WebSocket> {
  return new Promise((resolve, reject) => {
    const ws = new WebSocket(wsUrl, protocol);

    const timeoutId = setTimeout(() => {
      reject(new Error('[internal] WebSocket connection timeout'));
    }, timeout);

    ws.addEventListener('open', () => {
      clearTimeout(timeoutId);
      // Resolve the promise with the WebSocket instance when the connection is open
      resolve(ws);
    });

    ws.addEventListener('error', (event) => {
      clearTimeout(timeoutId);
      // Wrap browser WebSocket errors with [internal] tag so they can be filtered
      // from Clark's context (raw browser errors don't have useful stack traces)
      const message = 'message' in event && typeof event.message === 'string' ? event.message : 'WebSocket connection failed';
      reject(new Error(`[internal] ${message}`));
    });
  });
}
