import {
  WsConfig,
  WsInstance,
  WsConnectionStatus,
  WsMessageType,
  WsMessage,
  WsEvent,
  WsSendEventType
} from '../types';
import { computed, ref } from 'vue';
import { wsEventManager } from './event-manager';

// 创建WebSocket实例
export function createWsInstance(config: WsConfig): WsInstance {
  // 响应式状态
  const socket = ref<WebSocket | null>(null);
  const isConnected = ref(false);
  const isConnecting = ref(false);
  const reconnectCount = ref(0);
  const connectionStatus = ref<WsConnectionStatus>(
    WsConnectionStatus.DISCONNECTED
  );
  const messages = ref<WsMessage[]>([]);

  // 计算状态类
  const statusClass = computed(
    () => `status-${connectionStatus.value.toLowerCase()}`
  );

  // 内部方法
  const addMessage = (content: string, type: WsMessageType) => {
    messages.value.push({ content, type, timestamp: new Date() });
  };

  const addSystemMessage = (content: string) =>
    addMessage(content, WsMessageType.SYSTEM);

  // 事件处理器
  const handleOpen = (e: Event) => {
    isConnected.value = true;
    isConnecting.value = false;
    connectionStatus.value = WsConnectionStatus.CONNECTED;
    reconnectCount.value = 0;
    addSystemMessage('Connection established');
    wsEventManager.emit(WsEvent.CONNECTED, e);
  };

  const handleMessage = (e: MessageEvent) =>{
    addMessage(e.data, WsMessageType.INCOMING);
    const jsonData = JSON.parse(e.data);
    if (jsonData.event == WsEvent.LOCK_CLIENT_SCREEN) {
      // 锁屏
      wsEventManager.emit(WsEvent.LOCK_CLIENT_SCREEN, e);
    }
  }


  const handleError = (e: Event) => {
    isConnecting.value = false;
    connectionStatus.value = WsConnectionStatus.ERROR;
    addSystemMessage(`Error: ${e.type}`);
    !isConnected.value && attemptReconnect();
    console.log(e);
  };

  const handleClose = (e: CloseEvent) => {
    isConnected.value = false;
    isConnecting.value = false;
    connectionStatus.value = WsConnectionStatus.DISCONNECTED;
    addSystemMessage(`Connection closed: ${e.code} ${e.reason || ''}`);
    e.code !== 1000 && attemptReconnect();
  };

  // 重连逻辑
  const attemptReconnect = () => {
    if (reconnectCount.value >= config.reconnectAttempts) {
      return addSystemMessage('Max reconnect attempts reached');
    }

    reconnectCount.value++;
    addSystemMessage(
      `Reconnecting (${reconnectCount.value}/${config.reconnectAttempts})...`
    );
    setTimeout(connectSocket, config.reconnectDelay);
  };

  // 公开方法
  const connectSocket = () => {
    if (isConnected.value || isConnecting.value) return;

    isConnecting.value = true;
    connectionStatus.value = WsConnectionStatus.CONNECTING;
    addSystemMessage('Connecting...');

    try {
      socket.value = new WebSocket(config.url);

      socket.value.onopen = handleOpen;
      socket.value.onmessage = handleMessage;
      socket.value.onerror = handleError;
      socket.value.onclose = handleClose;
    } catch (error) {
      handleError(error as Event);
    }
  };

  const disconnectSocket = () => {
    socket.value?.close();
    socket.value = null;
    isConnected.value = false;
    isConnecting.value = false;
    connectionStatus.value = WsConnectionStatus.DISCONNECTED;
    reconnectCount.value = 0;
    addSystemMessage('Connection closed');
  };

  const sendMessage = (event: WsSendEventType, data: any) => {
    if (!socket.value || !isConnected.value || !data) return;

    const payload = JSON.stringify({ event, data });
    socket.value.send(payload);
    addMessage(payload, WsMessageType.OUTGOING);
  };

  const clearMessages = () => (messages.value = []);

  // 自动连接
  console.log('autoConnect->');
  config.autoConnect && connectSocket();

  return {
    isConnected,
    isConnecting,
    connectionStatus,
    messages,
    statusClass,
    events: wsEventManager,

    connectSocket,
    disconnectSocket,
    sendMessage,
    clearMessages
  };
}

// 全局实例
export let wsInstance: WsInstance | null = null;

// 初始化方法
export function initWs(config: WsConfig): WsInstance {
  return (wsInstance = wsInstance || createWsInstance(config));
}

