// eslint-disable-next-line
import { 
// @ts-ignore
UdpWebSocketClient } from 'udp-react-stencil-component-library';
import { useEffect, useRef, useCallback, useState, useMemo } from 'react';
import { getAccessToken } from '../utilities';
/**
 * React hook for managing WebSocket connections with automatic connection handling,
 * keep-alive support, and message management.
 *
 * @param url - The WebSocket URL to connect to (ws:// or wss://). If undefined, no connection is established.
 * @param options - Configuration options for the WebSocket connection behavior.
 *
 * @returns An object containing:
 * - `connected`: Boolean indicating if the WebSocket is currently connected
 * - `lastMessage`: The most recent message received from the server
 * - `lastError`: The most recent error event
 * - `send`: Async function to send messages (auto-connects if not connected)
 * - `reconnect`: Async function to manually reconnect the WebSocket
 * - `close`: Function to close the WebSocket connection
 * - `client`: Direct access to the underlying UdpWebSocketClient instance
 *
 * @example
 * ```tsx
 * // Basic usage
 * const { connected, send } = useUdpWebSocket(
 *   'wss://localhost:44371/UemService/api/v1/UdpWebSocket/21f2060a-1a09-4a03-81aa-4179db30b4eb/connect'
 * );
 *
 * const handleSend = () => {
 *   send({ payload: { message: "Hello world" } });
 * };
 * ```
 *
 * @example
 * ```tsx
 * // With message handling and keep-alive
 * const { connected, lastMessage, send } = useUdpWebSocket(
 *   'wss://localhost:44371/UemService/api/v1/UdpWebSocket/21f2060a-1a09-4a03-81aa-4179db30b4eb/connect',
 *   {
 *     onMessageReceived: (msg) => {
 *       console.log('Received:', msg);
 *     },
 *     onError: (error) => {
 *       console.error('WebSocket error:', error);
 *     },
 *     onClose: () => {
 *       console.log('Connection closed');
 *     },
 *     keepAliveIntervalSec: 30,  // Send ping every 30 seconds
 *     keepAliveTimeoutMin: 10     // Auto-close after 10 minutes
 *   }
 * );
 *
 * useEffect(() => {
 *   if (lastMessage) {
 *     // Handle received message
 *   }
 * }, [lastMessage]);
 * ```
 *
 * @remarks
 * - The hook automatically establishes a connection when the URL is provided
 * - Authentication tokens are automatically retrieved via `getAccessToken()`
 * - The `send()` function will automatically connect if not already connected
 * - Calling `close()` will close the connection; it will not auto-reconnect unless `reconnect()` is called
 * - The connection is automatically cleaned up when the component unmounts
 * - Keep-alive pings help maintain long-lived connections and detect dead connections
 */
export function useUdpWebSocket(url, options = {}) {
    const { onMessageReceived, onError, onClose, keepAliveIntervalSec = 0, keepAliveTimeoutMin = 0 } = options;
    const initialRetryCountRef = useRef(0);
    const MAX_INIT_RETRIES = 5;
    const INIT_RETRY_DELAY = 300;
    const [client] = useState(() => new UdpWebSocketClient());
    const [connected, setConnected] = useState(false);
    const [lastMessage, setLastMessage] = useState(null);
    const [lastError, setLastError] = useState(null);
    const messageHandlerRef = useRef(onMessageReceived);
    const errorHandlerRef = useRef(onError);
    const closeHandlerRef = useRef(onClose);
    useEffect(() => {
        messageHandlerRef.current = onMessageReceived;
    }, [onMessageReceived]);
    useEffect(() => {
        errorHandlerRef.current = onError;
    }, [onError]);
    useEffect(() => {
        closeHandlerRef.current = onClose;
    }, [onClose]);
    const connect = useCallback(async () => {
        if (!url)
            return;
        const c = client;
        if (c.isConnected)
            return;
        // Convert both values to ms
        const interval = (keepAliveIntervalSec || 0) * 1000;
        const timeout = (keepAliveTimeoutMin || 0) * 60 * 1000;
        await c.connect(url, getAccessToken, interval, timeout);
    }, [url, keepAliveIntervalSec, keepAliveTimeoutMin, client]);
    const send = useCallback(async (msg) => {
        const c = client;
        if (!c.isConnected) {
            await connect();
        }
        c.send(msg);
    }, [client, connect]);
    const close = useCallback(() => {
        client.close();
    }, [client]);
    const reconnect = useCallback(async () => {
        const c = client;
        c.close();
        setConnected(c.isConnected);
        await connect();
    }, [client, connect]);
    useEffect(() => {
        if (!url)
            return;
        const c = client;
        initialRetryCountRef.current = 0;
        c.onMessageReceived((msg) => {
            var _a;
            setLastMessage(msg);
            void ((_a = messageHandlerRef.current) === null || _a === void 0 ? void 0 : _a.call(messageHandlerRef, msg));
        });
        c.onOpen(() => {
            setConnected(c.isConnected);
        });
        c.onError((e) => {
            var _a;
            setLastError(e);
            void ((_a = errorHandlerRef.current) === null || _a === void 0 ? void 0 : _a.call(errorHandlerRef, e));
        });
        c.onClose((e) => {
            var _a;
            if (!connected && initialRetryCountRef.current < MAX_INIT_RETRIES) {
                initialRetryCountRef.current++;
                setTimeout(() => connect(), INIT_RETRY_DELAY);
            }
            void ((_a = closeHandlerRef.current) === null || _a === void 0 ? void 0 : _a.call(closeHandlerRef, e));
            setConnected(c.isConnected);
        });
        connect().catch(() => {
            // Initial connection failed
            console.warn('WebSocket initial connection failed');
        });
        initialRetryCountRef.current = MAX_INIT_RETRIES;
        return () => {
            c.close();
        };
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [url, client, connect]);
    return useMemo(() => ({
        connected,
        lastMessage,
        lastError,
        send,
        reconnect,
        close,
        client
    }), [connected, lastMessage, lastError, send, reconnect, close, client]);
}
//# sourceMappingURL=useUdpWebSocket.js.map