import { getAuthization } from '@/utils/userUtils';
import { useState, useEffect, useCallback, useRef } from 'react';
import SockJS from 'sockjs-client';
import { Client, IMessage } from '@stomp/stompjs';

interface WebSocketMessage {
  type: 'chat' | 'system' | 'notification' | 'friend' | 'error';
  content?: string;
  sender?: string;
  title?: string;
  timestamp?: Date;
  [key: string]: any; // 允许其他属性
}

interface WebSocketOptions {
  headers?: Record<string, string>;
  protocols?: string | string[];
}

const useWebSocket = (url: string, options?: WebSocketOptions) => {
  const [messages, setMessages] = useState<WebSocketMessage[]>([]);
  const [isConnected, setIsConnected] = useState(false);
  const [error, setError] = useState<Error | null>(null);
  const ws = useRef<WebSocket | null>(null);
  const stompClient = useRef<Client | null>(null);
  const reconnectAttempts = useRef(0);
  const maxReconnectAttempts = 5;
  const reconnectDelay = 3000;
 
  // 发送聊天消息
  const sendChatMessage = useCallback((toUserId: string, content: string) => {
    if (stompClient.current && stompClient.current.connected) {
      stompClient.current.publish({
        destination: '/app/chat/send',
        body: JSON.stringify({
          toUserId,
          content,
          timestamp: Date.now()
        })
      });
    } else {
      setError(new Error('WebSocket连接未建立'));
    }
  }, []);

  // 发送通用消息
  const sendMessage = useCallback((destination: string, body: any) => {
    if (stompClient.current && stompClient.current.connected) {
      stompClient.current.publish({
        destination,
        body: JSON.stringify(body)
      });
    } else {
      setError(new Error('WebSocket连接未建立'));
    }
  }, []);

  // 处理错误
  const handleError = useCallback((error: Event) => {
    setError(new Error(`WebSocket错误: ${(error as any).message || error.type}`));
  }, []);

  // 处理连接关闭
  const handleClose = useCallback((event: CloseEvent) => {
    setIsConnected(false);
    console.log(`连接关闭: ${event.code} ${event.reason}`);
    
    // 尝试重连
    if (reconnectAttempts.current < maxReconnectAttempts) {
      const delay = Math.pow(2, reconnectAttempts.current) * reconnectDelay;
      setTimeout(() => {
        reconnectAttempts.current++;
        connect();
      }, delay);
    }
  }, []);

  // 连接WebSocket
  const connect = useCallback(() => {
    try {
      // 构造带有查询参数的URL
      const urlObj = new URL(url, window.location.href);
      
      // 添加认证信息到查询参数
      const token = getAuthization();
      urlObj.searchParams.append('Authorization', token);
      
      // 添加其他 headers 作为查询参数
      if (options?.headers) {
        Object.entries(options.headers).forEach(([key, value]) => {
          urlObj.searchParams.append(key, value);
        });
      }

      const finalUrl = urlObj.toString();

      // 关闭之前的连接
      if (ws.current) {
        ws.current.close();
      }

      // 创建WebSocket连接
      ws.current = new SockJS(finalUrl, options?.protocols as any);
      
      // 创建STOMP客户端
      stompClient.current = new Client({
        webSocketFactory: () => ws.current as WebSocket,
        connectHeaders: {
          Authorization: getAuthization(),
        },
        debug: function (str) {
          console.log('[STOMP]', str);
        },
        reconnectDelay: 5000,
        heartbeatIncoming: 4000,
        heartbeatOutgoing: 4000,
      });

      // 连接成功的回调
      stompClient.current.onConnect = () => {
        setIsConnected(true);
        reconnectAttempts.current = 0;
        console.log('WebSocket连接已建立');
        
        // 订阅用户聊天消息
        stompClient.current?.subscribe('/user/queue/chat', (message: IMessage) => {
          try {
            const chatMessage = JSON.parse(message.body);
            setMessages(prev => [...prev, {
              type: 'chat',
              content: chatMessage.content,
              senderId: chatMessage.fromUserId,
              senderName: chatMessage.fromUserName,
              status: chatMessage.status,
              timestamp: new Date(chatMessage.timestamp || Date.now())
            }]);
          } catch (e) {
            console.error('解析聊天消息失败:', e);
          }
        });
        
        // 订阅好友通知
        stompClient.current?.subscribe('/user/queue/friend', (message: IMessage) => {
          try {
            const friendMessage = JSON.parse(message.body);
            console.log(message.body);
            
            setMessages(prev => [...prev, {
              type: 'friend',
              content: `好友请求: ${friendMessage.type}`,
              senderId: friendMessage.fromUserId,
              senderName: friendMessage.fromUserName,
              status: friendMessage.status,
              timestamp: new Date()
            }]);
          } catch (e) {
            console.error('解析好友消息失败:', e);
          }
        });
        
        // 订阅系统通知
        stompClient.current?.subscribe('/user/queue/notification', (message: IMessage) => {
          try {
            const notification = JSON.parse(message.body);
            console.log('notification', message);
            setMessages(prev => [...prev, {
              type: 'notification',
              title: notification.title,
              content: notification.message || notification.content,
              status: notification.status,
              timestamp: new Date(notification.timestamp || Date.now())
            }]);
          } catch (e) {
            console.error('解析通知消息失败:', e);
          }
        });
      };
      
      // STOMP错误处理
      stompClient.current.onStompError = (frame) => {
        console.error('Broker reported error: ' + frame.headers['message']);
        console.error('Additional details: ' + frame.body);
        setError(new Error(`STOMP错误: ${frame.headers['message']}`));
      };

      // 激活客户端
      stompClient.current.activate();
      
    } catch (e) {
      setError(e as Error);
    }
  }, [url, options]);

  // 初始化连接
  useEffect(() => {
    connect();
    return () => {
      if (stompClient.current) {
        stompClient.current.deactivate();
      }
      if (ws.current) {
        ws.current.close();
      }
    };
  }, [connect]);

  return {
    messages,
    sendChatMessage,
    sendMessage,
    isConnected,
    error
  };
};

export default useWebSocket;