// node native
import type * as http from 'http';
import type * as https from 'https';

export type { http, https };

// third party scope - ws types
import type * as wsTypes from 'ws';

export namespace ws {
  export type WebSocket = wsTypes.WebSocket;
  export type WebSocketServer = wsTypes.WebSocketServer;
  export type RawData = wsTypes.RawData;
}

/**
 * Unified WebSocket type supporting both browser and Node.js environments
 */
export type TWebSocket = WebSocket | ws.WebSocket;

/**
 * Message event type for WebSocket messages (browser and Node.js compatible)
 */
export type TMessageEvent = MessageEvent | { data: string };

/**
 * WebSocket-like interface for adapters (e.g., smartserve peer adapter)
 */
export interface IWebSocketLike {
  readyState: number;
  send(data: string): void;
  close(code?: number, reason?: string): void;
  addEventListener(event: 'message', listener: (event: TMessageEvent) => void): void;
  addEventListener(event: 'close', listener: () => void): void;
  addEventListener(event: 'error', listener: () => void): void;
  removeEventListener?(event: string, listener: (...args: any[]) => void): void;
}

// smartserve compatibility interface (for setExternalServer)
// This mirrors the IWebSocketPeer interface from smartserve
export interface ISmartserveWebSocketPeer {
  id: string;
  url: string;
  readyState: 0 | 1 | 2 | 3;
  protocol: string;
  extensions: string;
  send(data: string): void;
  sendBinary(data: Uint8Array | ArrayBuffer): void;
  close(code?: number, reason?: string): void;
  ping(data?: Uint8Array): void;
  terminate(): void;
  context: any;
  data: Map<string, unknown>;
  tags: Set<string>;
}

export interface ISmartserveWebSocketMessage {
  type: 'text' | 'binary';
  text?: string;
  data?: Uint8Array;
  size: number;
}

export interface ISmartserveWebSocketHooks {
  onOpen?: (peer: ISmartserveWebSocketPeer) => void | Promise<void>;
  onMessage?: (peer: ISmartserveWebSocketPeer, message: ISmartserveWebSocketMessage) => void | Promise<void>;
  onClose?: (peer: ISmartserveWebSocketPeer, code: number, reason: string) => void | Promise<void>;
  onError?: (peer: ISmartserveWebSocketPeer, error: Error) => void | Promise<void>;
}
