export type UseWebSocketSendable = string | ArrayBufferLike | Blob | ArrayBufferView
export interface UseWebSocketOptionsHeartbeat {
  /**
   * The heartbeat message to send.
   *
   * @defaultValue 'ping'
   */
  message?: UseWebSocketSendable
  /**
   * The interval at which to send a heartbeat message.
   *
   * @defaultValue 1_000
   */
  interval?: number
  /**
   * The timeout for the server to respond to the heartbeat message.
   *
   * @defaultValue 1_000
   */
  responseTimeout?: number
  /**
   * The message considered as the server's response to the heartbeat, default to true, meaning any message returned is considered a heartbeat response (considered the server is alive)
   * 
   * Can pass a message string, or a function that returns true if the message is considered a heartbeat response, to be used with responseTimeout, when timeout occurs, it is considered that the server is disconnected.
   *
   * @defaultValue true
   */
  responseMessage?: true | UseWebSocketSendable | ((data: UseWebSocketSendable) => boolean)
}
export interface UseWebSocketOptionsReconnect {
  /**
   * The number of reconnection attempts, can be the number of retry attempts or a function returning a boolean, the function continues reconnecting when returning true, and stops when returning false.
   * 
   * @defaultValue () => true
   */
  count?: number | (() => boolean)
  /**
   * The interval between reconnection attempts.
   * 
   * @defaultValue 1_000
   */
  interval?: number
  /**
   * A callback function when reconnection fails.
   */
  onFailed?: (event: CloseEvent, ws: WebSocket) => void
}
export interface UseWebSocketOptions {
  /**
   * A callback function when WebSocket's open event is triggered.
   *
   * @defaultValue undefined
   */
  onOpen?: (event: Event, ws: WebSocket) => void
  /**
   * A callback function when WebSocket's close event is triggered.
   *
   * @defaultValue undefined
   */
  onClose?: (event: CloseEvent, ws: WebSocket) => void
  /**
   * A callback function when WebSocket's error event is triggered.
   *
   * @defaultValue undefined
   */
  onError?: (event: Event, ws: WebSocket) => void
  /**
   * A callback function when WebSocket's message event is triggered.
   *
   * @defaultValue undefined
   */
  onMessage?: (event: MessageEvent, ws: WebSocket) => void
  /**
   * A callback function that is called when the WebSocket connection fails to open,
   * such as an error or an invalid URL, which will cause the ws to fail to create a connection and close the connection.
   *
   * @defaultValue undefined
   */
  onOpenFailed?: (event: CloseEvent, ws: WebSocket) => void
  /**
   * Heartbeat configuration, set to true to use default configuration, refer to UseWebSocketOptionsHeartbeat's default settings.
   *
   * @defaultValue false
   */
  heartbeat?: boolean | UseWebSocketOptionsHeartbeat
  /**
   * Whether to automatically reconnect when the connection is dropped, count can be the number of retries or a function, the function continues reconnecting when returning true, and stops when returning false.
   *
   * @defaultValue true => { count: () => true, interval: 1_000 }
   */
  reconnect?: boolean | UseWebSocketOptionsReconnect
  /**
   * Whether to immediately open the WebSocket connection, defaults to true when a WS URL is provided, otherwise false.
   */
  immediate?: boolean
  /**
   * Whether to close the WebSocket connection when the component is unmounted.
   *
   * @defaultValue true
   */
  closeOnUnmount?: boolean
  /**
   * Additional WebSocket subprotocols.
   *
   * @defaultValue []
   */
  protocols?: string | string[]
  /**
   * Filters messages to the `onMessage` callback, return `true` to ignore the message.
   *
   * Useful for filtering out heartbeat messages.
   *
   * @defaultValue undefined
   */
  filter?: (event: MessageEvent, ws: WebSocket) => boolean
}