import { AsyncVoidIOResult, IOResult } from 'happy-rusty';

/**
 * 公共类型定义模块。
 *
 * @module defines
 */
/**
 * 数据源类型，可以是 string 或者 BufferSource。
 * @since 1.8.0
 * @example
 * ```ts
 * // 字符串类型
 * const strData: DataSource = 'Hello, World!';
 *
 * // ArrayBuffer 类型
 * const bufferData: DataSource = new ArrayBuffer(8);
 *
 * // Uint8Array 类型
 * const u8aData: DataSource = new Uint8Array([1, 2, 3]);
 * ```
 */
type DataSource = string | BufferSource;

/**
 * WebSocket 连接状态，小游戏环境可用。
 * @since 1.6.0
 * @example
 * ```ts
 * import { SocketReadyState, connectSocket } from 'minigame-std';
 *
 * const socket = connectSocket('wss://example.com');
 * if (socket.readyState === SocketReadyState.OPEN) {
 *     console.log('连接已打开');
 * }
 * ```
 */
declare const SocketReadyState: {
    /**
     * WebSocket.CONNECTING
     */
    readonly CONNECTING: 0;
    /**
     * WebSocket.OPEN
     */
    readonly OPEN: 1;
    /**
     * WebSocket.CLOSING
     */
    readonly CLOSING: 2;
    /**
     * WebSocket.CLOSED
     */
    readonly CLOSED: 3;
};
/**
 * WebSocket 事件监听器映射接口，定义了与 WebSocket 事件对应的回调函数类型。
 * @since 1.0.0
 * @example
 * ```ts
 * import type { SocketListenerMap } from 'minigame-std';
 *
 * const onMessage: SocketListenerMap['message'] = (data) => {
 *     console.log('收到消息:', data);
 * };
 * ```
 */
interface SocketListenerMap {
    /**
     * 当 WebSocket 连接成功打开时触发。
     */
    open(): void;
    /**
     * 当 WebSocket 连接关闭时触发。
     * @param code - 表示关闭连接的状态码。
     * @param reason - 表示关闭连接的原因。
     */
    close(code: number, reason: string): void;
    /**
     * 当 WebSocket 接收到消息时触发。
     * @param data - 接收到的消息数据，可以是字符串或者 ArrayBuffer。
     */
    message(data: string | ArrayBuffer): void;
    /**
     * 当 WebSocket 连接发生错误时触发。
     * @param err - 发生的错误对象。
     */
    error(err: Error): void;
}
/**
 * WebSocket 接口定义，描述了 WebSocket 的基本操作方法。
 * @since 1.0.0
 * @example
 * ```ts
 * import type { ISocket } from 'minigame-std';
 *
 * function handleSocket(socket: ISocket) {
 *     socket.addEventListener('message', (data) => {
 *         console.log('收到:', data);
 *     });
 *     socket.send('Hello');
 * }
 * ```
 */
interface ISocket {
    /**
     * WebSocket 的连接状态。
     */
    readonly readyState: number;
    /**
     * 添加事件监听器到 WebSocket 对象。
     * @typeParam K - 限定为 WebSocketEventMap 的键类型。
     * @param type - 事件类型，如 'open', 'close', 'message', 'error'。
     * @param listener - 对应事件的监听器回调函数。
     * @returns 返回对应的`removeEventListener代理函数`。
     */
    addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: SocketListenerMap[K]): () => void;
    /**
     * 发送数据到 WebSocket 服务器。
     * @param data - 要发送的数据，可以是字符串、ArrayBuffer 或 ArrayBufferView。
     * @returns 返回一个 Promise，其解析为发送结果，成功时返回 true，失败时返回 Error。
     */
    send(data: DataSource): AsyncVoidIOResult;
    /**
     * 关闭 WebSocket 连接。
     * @param code - 可选的状态码，表示关闭连接的原因。
     * @param reason - 可选的字符串，解释为什么要关闭连接。
     */
    close(code?: number, reason?: string): void;
}
/**
 * 创建Socket的可选参数。
 * @since 1.0.0
 * @example
 * ```ts
 * import { connectSocket, type SocketOptions } from 'minigame-std';
 *
 * const options: SocketOptions = {
 *     protocols: ['protocol1', 'protocol2'],
 *     headers: { 'Authorization': 'Bearer token' },
 * };
 * const socket = connectSocket('wss://example.com', options);
 * ```
 */
interface SocketOptions extends Omit<WechatMinigame.ConnectSocketOption, 'url' | 'header' | 'complete' | 'success' | 'fail'> {
    headers?: Record<string, string>;
}

/**
 * WebSocket 模块，提供创建和管理 WebSocket 连接的功能。
 * @module socket
 */

/**
 * 创建并返回一个 WebSocket 连接。
 * @param url - WebSocket 服务器的 URL。
 * @param options - 可选的参数。
 * @returns 返回一个实现了 ISocket 接口的 WebSocket 对象。
 * @since 1.0.0
 * @example
 * ```ts
 * const socket = connectSocket('wss://echo.websocket.org');
 *
 * socket.addEventListener('open', () => {
 *     console.log('连接已建立');
 *     socket.send('Hello, Server!');
 * });
 *
 * socket.addEventListener('message', (data) => {
 *     console.log('收到消息:', data);
 * });
 *
 * socket.addEventListener('close', (code, reason) => {
 *     console.log('连接已关闭:', code, reason);
 * });
 *
 * socket.addEventListener('error', (error) => {
 *     console.error('连接错误:', error);
 * });
 *
 * // 关闭连接
 * socket.close();
 * ```
 */
declare function connectSocket(url: string, options?: SocketOptions): IOResult<ISocket>;

export { SocketReadyState, connectSocket };
export type { ISocket, SocketListenerMap, SocketOptions };
