import { useState, useEffect, useRef, useCallback } from 'react';

interface WebSocketOptions {
  reconnectInterval?: number;
  maxReconnectAttempts?: number;
  onOpen?: (event: Event) => void;
  onClose?: (event: CloseEvent) => void;
  onError?: (event: Event) => void;
  onMessage?: (event: MessageEvent) => void;
}

interface WebSocketHook {
  connect: (url: string) => void;
  disconnect: () => void;
  sendMessage: (message: string | object) => void;
  readyState: number;
  isConnected: boolean;
}

const useWebSocket = (options: WebSocketOptions = {}): WebSocketHook => {
  const {
    reconnectInterval = 3000,
    maxReconnectAttempts = 0,
    onOpen,
    onClose,
    onError,
    onMessage
  } = options;

  const [readyState, setReadyState] = useState<number>(WebSocket.CLOSED);
  const [isConnected, setIsConnected] = useState<boolean>(false);
  const wsRef = useRef<WebSocket | null>(null);
  const reconnectAttemptsRef = useRef<number>(0);
  const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  const urlRef = useRef<string>('');

  // 清理重连定时器
  const clearReconnectTimeout = useCallback(() => {
    if (reconnectTimeoutRef.current) {
      clearTimeout(reconnectTimeoutRef.current);
      reconnectTimeoutRef.current = null;
    }
  }, []);

  // 断开连接
  const disconnect = useCallback(() => {
    clearReconnectTimeout();
    if (wsRef.current) {
      wsRef.current.close();
      wsRef.current = null;
    }
    setReadyState(WebSocket.CLOSED);
    setIsConnected(false);
  }, [clearReconnectTimeout]);

  // 发送消息
  const sendMessage = useCallback((message: string | object) => {
    if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
      const messageStr = typeof message === 'string' ? message : JSON.stringify(message);
      wsRef.current.send(messageStr);
    } else {
      console.warn('WebSocket is not connected. Cannot send message.');
    }
  }, []);

  // 连接WebSocket
  const connect = useCallback((url: string) => {
    // 先断开现有连接
    disconnect();
    
    urlRef.current = url;
    
    try {
      const ws = new WebSocket(url);
      wsRef.current = ws;
      
      ws.onopen = (event) => {
        setReadyState(WebSocket.OPEN);
        setIsConnected(true);
        reconnectAttemptsRef.current = 0;
        onOpen?.(event);
      };
      
      ws.onclose = (event) => {
        setReadyState(WebSocket.CLOSED);
        setIsConnected(false);
        onClose?.(event);
        
        // 处理重连
        if (reconnectAttemptsRef.current < maxReconnectAttempts) {
          reconnectAttemptsRef.current++;
          reconnectTimeoutRef.current = setTimeout(() => {
            connect(url);
          }, reconnectInterval);
        }
      };
      
      ws.onerror = (event) => {
        setIsConnected(false);
        onError?.(event);
      };
      
      ws.onmessage = (event) => {
        onMessage?.(event);
      };
      
      setReadyState(WebSocket.CONNECTING);
    } catch (error) {
      console.error('Failed to create WebSocket connection:', error);
      setIsConnected(false);
      setReadyState(WebSocket.CLOSED);
    }
  }, [disconnect, maxReconnectAttempts, onOpen, onClose, onError, onMessage, reconnectInterval]);

  // 组件卸载时清理
  useEffect(() => {
    return () => {
      disconnect();
    };
  }, [disconnect]);

  return {
    connect,
    disconnect,
    sendMessage,
    readyState,
    isConnected
  };
};

export default useWebSocket;