// src/Service/Im/WebSocket.ts

import { EventHandler } from '@/Service/Comm/EventHandler';
import { Service, ImConnectService } from '@/Service/Im/ImConnectService';

class WebSocketManager {
    private socketTask: UniApp.SocketTask | null = null;
    private heartbeatInterval: ReturnType<typeof setInterval> | null = null;
    private readonly heartbeat: number = 30000; // 建议心跳30秒
    private isConnecting: boolean = false; // 连接状态锁
    private isUserClose: boolean = false; // 是否是用户主动关闭

    public ConnectSocketInit(): void {
        if (this.isConnecting || this.socketTask) {
            console.warn('WebSocket 正在连接或已连接，请勿重复调用。');
            return;
        }
        this.isConnecting = true;
        this.isUserClose = false;

        ImConnectService.GetConnect().then((res: any) => {
            if (res.code !== 0) {
                this.isConnecting = false;
                // Service.Msg('获取连接地址失败');
                return;
            }

            Service.SetUserClientId(res.data.websocketId);

            this.socketTask = uni.connectSocket({
                url: res.data.server,
                header: { 'content-type': 'application/json' },
                // 推荐在小程序端开启 BSON
                // #ifdef MP-WEIXIN
                // protocols: ['bson'],
                // #endif
                success: () => {}, // success回调仅表示任务创建成功
            });
            
            // ✅ 绑定事件监听 (在 onOpen 外部)
            this.socketTask.onOpen(() => {
                console.log('==============WebSocket连接正常=============');
                this.isConnecting = false;
                this.startHeartbeat();
                EventHandler.ConnectBus();
            });

            this.socketTask.onMessage((data: any) => {
                console.log('接收到消息');
                EventHandler.Events(data);
            });

            this.socketTask.onClose((e: any) => {
                console.log('========WebSocket连接已被关闭========', e);
                this.isConnecting = false;
                this.stopHeartbeat();
                this.socketTask = null; // 清理实例
                // 如果不是用户主动关闭，则触发重连
                if (!this.isUserClose) {
                    this.reconnect();
                }
            });
            
            this.socketTask.onError((err: any) => {
                console.error('========WebSocket连接发生错误========', err);
                this.isConnecting = false;
                // 错误发生时，通常也会触发 onClose，由 onClose 统一处理重连
            });
        }).catch(err => {
            this.isConnecting = false;
            console.error('GetConnect API 请求失败:', err);
        });
    }

    private startHeartbeat(): void {
        this.stopHeartbeat(); // 先停止旧的，确保只有一个
        const heartbeatData = JSON.stringify({ code: 'Heart', method: 'Heart' });
        
        this.heartbeatInterval = setInterval(() => {
            console.log('======发送心跳检测======');
            this.send(heartbeatData);
        }, this.heartbeat);
    }

    private stopHeartbeat(): void {
        if (this.heartbeatInterval) {
            clearInterval(this.heartbeatInterval);
            this.heartbeatInterval = null;
        }
    }

    // 重新连接 (带延迟和重试次数)
    public reconnect(): void {
        console.log('准备在3秒后尝试重连...');
        setTimeout(() => {
            console.log('正在尝试重连...');
            this.ConnectSocketInit();
            // 在您的 EventHandler 或全局事件总线中可以增加重试次数限制
            uni.$emit('ImReconnecting');
        }, 3000); // 延迟3秒重连，避免频繁请求
    }

    public CloseSocket(reason: string = 'user close'): void {
        if (!this.socketTask) return;

        this.isUserClose = true;
        this.stopHeartbeat(); // ✅ 立即停止心跳
        
        this.socketTask.close({
            code: 1000,
            reason: reason,
            success: () => { // ✅ 使用箭头函数
                console.log('===============关闭 WebSocket 成功===================');
            },
            fail: (err) => { // ✅ 使用箭头函数
                console.log('===================关闭 WebSocket 失败=====================', err);
            }
        });
    }

    public send(value: any): void {
        if (this.socketTask && this.socketTask.readyState === 1) { // 检查连接状态
            this.socketTask.send({
                data: value,
                success: () => {}, // ✅ 使用箭头函数
                fail: (err) => { // ✅ 使用箭头函数
                    console.error('发送消息失败:', err);
                    // 发送失败通常意味着连接已断开，onClose会处理重连
                }
            });
        } else {
            console.error('WebSocket 未连接，无法发送消息。');
            // 可以考虑将消息放入一个队列，等重连成功后再发送
        }
    }
}

// 导出单例模式
export const WebSocket = new WebSocketManager();