import { io, Socket as IOSocket } from 'socket.io-client'
import type { SocketMethods } from './types'

export function createSocketMethods(): SocketMethods {
    let socket: IOSocket | null = null
    const handlers: Record<string, ((...args: any[]) => void)[]> = {}

    return {
        /**
         * Establish a Socket.IO connection
         */
        connect() {
            if (!socket) {
                // Default connection to the server's base URL
                const url =
                    globalThis?.window?.location?.origin ||
                    'http://localhost:3000'
                socket = io(url)
            }

            if (socket && !socket.connected) {
                socket.connect()
            }
        },

        /**
         * Disconnect the Socket.IO connection
         */
        disconnect() {
            if (socket && socket.connected) {
                socket.disconnect()
            }
        },

        /**
         * Listen for an event on the Socket.IO connection
         */
        on(event: string, handler: (...args: any[]) => void) {
            if (!handlers[event]) {
                handlers[event] = []
            }
            handlers[event].push(handler)

            if (socket) {
                socket.on(event, handler)
            }
        },

        /**
         * Remove listeners for an event on the Socket.IO connection
         */
        off(event: string) {
            if (socket && handlers[event]) {
                for (const handler of handlers[event]) {
                    socket.off(event, handler)
                }
                delete handlers[event]
            }
        },

        /**
         * Emit an event on the Socket.IO connection
         */
        emit(event: string, ...args: any[]) {
            if (socket) {
                socket.emit(event, ...args)
                return true
            }

            return false
        },
    }
}
