import { reactive, watchEffect } from "vue"
interface WebSocketState {
    ws: WebSocket | null;
    isConnected: boolean;
    error: Error | null;
    data: any;
    heartbeatInterval: number;
    heartbeatTimer: any,
    connectionAttempts: number,
    maxConnectionAttempts: number
    reconnectInterval: number
    unload?: boolean
}
interface WebSocketConfig {
    url: string;
    onOpen?: (instance: any) => void;
    onError?: (event: Event) => void;
    onClose?: (event: CloseEvent) => void;
    onMessage?: (data: any) => void;
}

export default function useWebsocket(config: WebSocketConfig) {
    const state = reactive<WebSocketState>({
        ws: null,
        isConnected: false,
        error: null,
        data: null,
        heartbeatInterval: 5000,
        heartbeatTimer: null,
        connectionAttempts: 0,
        maxConnectionAttempts: 5,
        reconnectInterval: 5000,
        unload: false
    })

    const connect = () => {
        state.ws = uni.connectSocket({
            url: config.url,
            complete: () => { },
            fail: (error) => {
                console.log('连接失败', error);

            }
        })

        state.ws?.onOpen(() => {
            console.log(`WebSocket connection to ${config.url} established`);
            state.isConnected = true
            state.connectionAttempts = 0
            state.unload = false
            config.onOpen?.(state.ws)
            // startHeartbeat()
        })

        state.ws?.onError(({ errMsg }) => {
            console.log(`WebSocket connection error: ${errMsg}`);
            state.error = errMsg
            config.onError?.(errMsg)
        })

        state.ws?.onClose((event) => {
            console.warn(`WebSocket connection to ${config.url} closed: ${event.code} ${event.reason}`);
            state.isConnected = false
            config.onClose?.(event)
            state.ws = null
            // stopHeartbeat()
            // state.heartbeatTimer = null
            if (state.unload) return
            if (state.connectionAttempts < state.maxConnectionAttempts) {
                setTimeout(() => {
                    state.connectionAttempts++
                    connect()
                }, state.reconnectInterval)
            }
        })

        state.ws?.onMessage((event) => {
            state.data = event.data
            config.onMessage?.(event.data)
        })
    }

    const close = (type?: string) => {
        state.ws?.close()
        state.ws = null
        stopHeartbeat()
        state.heartbeatTimer = null
        state.unload = type === 'unload'
    }
    const send = (data: any) => {
        state.ws?.send({ data })
    }

    const sendHeartbeat = () => {
        state.ws?.send({
            data: Date.now()
        })
    }
    const startHeartbeat = () => {
        state.heartbeatTimer = setInterval(sendHeartbeat, state.heartbeatInterval)
    }
    const stopHeartbeat = () => {
        clearInterval(state.heartbeatTimer)
    }

    return {
        data: state.data,
        connect,
        send,
        close
    }
}
