// common/websocket-manager.js

import * as wsApi from './wssocket';
import * as msgType from './messageType';
import * as enums from './enums';

class WebSocketManager {
    constructor() {
        if (WebSocketManager.instance) return WebSocketManager.instance;
        WebSocketManager.instance = this;

        // 状态标志
        this.isInit = false;
        this.isExit = false;
        this.reconnecting = false;
        this.audioTip = null;
        this.WS_URL=this.$wsUrl

        // Store 引用（需外部注入）
        this.chatStore = null;
        this.userId=null;
        // 事件监听器（供页面注册）
        this.messageListeners = [];
    }

    /**
     * 初始化 WebSocket 管理器
     * @param {Object} stores - 各个 store 实例
     * @param {string} accessToken - 用户 token
     */
    init(stores, accessToken) {
        if (this.isInit) return;

        this.chatStore = stores.chatStore;
        this.userId=stores.userId;
        this.isExit = false;
        this.reconnecting = false;

        // 加载本地数据并启动 WebSocket
        this.loadStore()
            .then(() => {
                this.initWebSocket(accessToken);
                this.isInit = true;
            })
            .catch((e) => {
                console.error(e);
                this.exit();
            });
    }

    initWebSocket(accessToken) {
        wsApi.connect(this.WS_URL, accessToken);

        wsApi.onConnect(() => {
            if (this.reconnecting) {
                this.onReconnectWs();
            } else {
                // 首次连接，拉取离线消息
                this.pullPrivateOfflineMessage(this.chatStore.privateMsgMaxId).catch(() => {});
                this.pullGroupOfflineMessage(this.chatStore.groupMsgMaxId).catch(() => {});
            }
        });

        wsApi.onMessage((cmd, msgInfo) => {
            // 分发原始消息给外部监听器
            this.messageListeners.forEach(listener => listener(cmd, msgInfo));

            // 内部业务处理
            if (cmd == 2) {
                // 异地登录
                uni.showModal({
                    content: '您已在其他地方登录，将被强制下线',
                    showCancel: false,
                });
                this.exit();
            } else if (cmd == 3) {
                this.handlePrivateMessage(msgInfo);
            } else if (cmd == 4) {
                this.handleGroupMessage(msgInfo);
            } else if (cmd == 5) {
                this.handleSystemMessage(msgInfo);
            }
        });

        wsApi.onClose((res) => {
            console.log("ws断开", res);
            this.reconnect(accessToken);
        });
    }


    /**
     * 重新连接（token 刷新后调用）
     * @param {string} accessToken
     */
    reconnect(accessToken) {
        if (this.isExit) return;
        this.reconnecting = true;
        wsApi.reconnect(this.WS_URL, accessToken);
    }

    /**
     * 关闭连接并退出登录
     */
    exit() {
        console.log("WebSocket exit");
        this.isExit = true;
        wsApi.close(3099);
        // uni.removeStorageSync("loginInfo");
        // uni.reLaunch({ url: "/pages/login/login" });
        this.unloadStore();
    }

    /**
     * 注册消息监听器（页面可用来接收新消息通知）
     * @param {Function} listener - (cmd, msgInfo) => {}
     */
    addMessageListener(listener) {
        if (typeof listener === 'function') {
            this.messageListeners.push(listener);
        }
    }

    /**
     * 移除消息监听器
     */
    removeMessageListener(listener) {
        const index = this.messageListeners.indexOf(listener);
        if (index !== -1) this.messageListeners.splice(index, 1);
    }

    // ============= 私有方法 =============


    // 视频通话相关（可根据需要保留或删除）
    handleRtcPrivate(msg) {
        // #ifdef MP-WEIXIN
        // return; // 小程序不支持
        // // #endif
        // let delayTime = 100;
        // if (msg.type === enums.MESSAGE_TYPE.RTC_CALL_VOICE || msg.type === enums.MESSAGE_TYPE.RTC_CALL_VIDEO) {
        //     const mode = msg.type === enums.MESSAGE_TYPE.RTC_CALL_VIDEO ? "video" : "voice";
        //     const pages = getCurrentPages();
        //     const curPage = pages[pages.length - 1].route;
        //     if (curPage !== "pages/chat/chat-private-video") {
        //         const friend = this.loadFriendInfo(msg.selfSend ? msg.recvId : msg.sendId);
        //         const friendInfo = encodeURIComponent(JSON.stringify(friend));
        //         uni.navigateTo({
        //             url: `/pages/chat/chat-private-video?mode=${mode}&friend=${friendInfo}&isHost=false`,
        //         });
        //         delayTime = 500;
        //     }
        // }
        // setTimeout(() => {
        //     uni.$emit('WS_RTC_PRIVATE', msg);
        // }, delayTime);
    }

    handleRtcGroup(msg) {
        // #ifdef MP-WEIXIN
        return;
        // #endif
        let delayTime = 100;
        if (msg.type === enums.MESSAGE_TYPE.RTC_GROUP_SETUP) {
            const pages = getCurrentPages();
            const curPage = pages[pages.length - 1].route;
            if (curPage !== "pages/chat/chat-group-video") {
                const userInfos = encodeURIComponent(msg.content);
                const inviterId = msg.sendId;
                const groupId = msg.groupId;
                uni.navigateTo({
                    url: `/pages/chat/chat-group-video?groupId=${groupId}&isHost=false&inviterId=${inviterId}&userInfos=${userInfos}`,
                });
                delayTime = 500;
            }
        }
        setTimeout(() => {
            uni.$emit('WS_RTC_GROUP', msg);
        }, delayTime);
    }



    playAudioTip() {
        // 音频播放实现（如需）
        // this.audioTip = uni.createInnerAudioContext();
        // this.audioTip.src = "/static/audio/tip.wav";
        // this.audioTip.play();
    }

    async refreshToken(loginInfo) {
        // if (!loginInfo || !loginInfo.refreshToken) {
        //     throw new Error("No refreshToken");
        // }
        // const newLoginInfo = await http({
        //     url: '/refreshToken',
        //     method: 'PUT',
        //     header: { refreshToken: loginInfo.refreshToken },
        // });
        // uni.setStorageSync("loginInfo", newLoginInfo);
        // return newLoginInfo;
    }




}

// 导出单例
const wsManager = new WebSocketManager();
export default wsManager;
