import { defineStore } from "pinia";
import { ref } from "vue";

/**
 * WebSocket Store（浏览器端）
 * 与商家端 @/store/websocket 消息格式一致，用于分享动态、聊天等
 */
export const useWebSocketStore = defineStore("websocket", () => {
  const socket = ref<WebSocket | null>(null);
  const isConnected = ref(false);
  const isConnecting = ref(false);
  const lastConnectedUrl = ref("");

  // 消息订阅（用于聊天等）
  const messageHandlers = new Map<string, Array<(msg: any) => void>>();

  const connect = (url: string): Promise<boolean> => {
    if (isConnected.value && lastConnectedUrl.value === url) {
      return Promise.resolve(true);
    }
    if (socket.value) {
      try {
        socket.value.close();
      } catch (e) {
        console.warn("关闭旧连接失败:", e);
      }
      socket.value = null;
      isConnected.value = false;
    }

    isConnecting.value = true;
    lastConnectedUrl.value = url;

    return new Promise(resolve => {
      try {
        const ws = new WebSocket(url);
        socket.value = ws;

        ws.onopen = () => {
          isConnected.value = true;
          isConnecting.value = false;
          resolve(true);
        };

        ws.onmessage = (event: MessageEvent) => {
          try {
            const message = JSON.parse(event.data);
            const category = message.category || "message";
            // 按 category 分发
            const handlers = messageHandlers.get(category);
            if (handlers?.length) {
              handlers.forEach(cb => cb(message));
            }
            // 兼容：若后端推送的 category 不是 "message" 但明显是聊天消息，也派发给 message 订阅者（解决业主发消息不实时更新）
            const isChatLike =
              category !== "message" &&
              (message.senderId != null || message.receiverId != null) &&
              (message.text != null || message.content != null || message.type != null);
            if (isChatLike) {
              const messageHandlersList = messageHandlers.get("message");
              if (messageHandlersList?.length) {
                messageHandlersList.forEach(cb => cb(message));
              }
            }
          } catch (_) {}
        };

        ws.onclose = () => {
          isConnected.value = false;
          isConnecting.value = false;
          socket.value = null;
        };

        ws.onerror = () => {
          isConnected.value = false;
          isConnecting.value = false;
          resolve(false);
        };
      } catch (e) {
        console.error("WebSocket 连接异常:", e);
        isConnecting.value = false;
        resolve(false);
      }
    });
  };

  /** 订阅消息（返回取消订阅函数） */
  const subscribe = (type: string, callback: (msg: any) => void) => {
    if (!messageHandlers.has(type)) {
      messageHandlers.set(type, []);
    }
    messageHandlers.get(type)!.push(callback);
    return () => {
      const handlers = messageHandlers.get(type) || [];
      messageHandlers.set(
        type,
        handlers.filter(h => h !== callback)
      );
    };
  };

  const sendMessage = (data: Record<string, unknown>): Promise<boolean> => {
    return new Promise(resolve => {
      if (!isConnected.value || !socket.value || socket.value.readyState !== WebSocket.OPEN) {
        console.warn("WebSocket 未连接，无法发送消息");
        resolve(false);
        return;
      }
      try {
        const message = JSON.stringify(data);
        socket.value.send(message);
        resolve(true);
      } catch (e) {
        console.error("消息发送异常:", e);
        resolve(false);
      }
    });
  };

  const disconnect = () => {
    if (socket.value) {
      try {
        socket.value.close();
      } catch (_) {}
      socket.value = null;
    }
    isConnected.value = false;
    isConnecting.value = false;
    lastConnectedUrl.value = "";
    messageHandlers.clear();
  };

  return {
    socket,
    isConnected,
    isConnecting,
    lastConnectedUrl,
    connect,
    sendMessage,
    disconnect,
    subscribe
  };
});
