/**
 * WebSocket 管理类
 */
import { useGlobalStore } from '@/stores'

class WebSocketManager {
	private ws: WebSocket | null = null
	private url: string = ''
	private reconnectTimer: number | null = null
	private reconnectAttempts: number = 0
	private maxReconnectAttempts: number = 5
	private reconnectInterval: number = 3000
	private heartbeatTimer: number | null = null
	private heartbeatInterval: number = 30000
	private isManualClose: boolean = false

	/**
	 * 连接 WebSocket
	 * @param token 用户 token
	 */
	connect(token: string) {
		if (!token) {
			console.warn('WebSocket: token 为空，无法建立连接')
			return
		}

		// 如果已经有连接在进行中，先关闭
		if (this.ws) {
			if (this.ws.readyState === WebSocket.CONNECTING) {
				console.log('WebSocket 正在连接中，跳过重复连接')
				return
			}
			if (this.ws.readyState === WebSocket.OPEN) {
				console.log('WebSocket 已连接，跳过重复连接')
				return
			}
		}

		// 根据当前页面协议自动选择 ws 或 wss
		// const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
		const protocol = 'wss:'
		
		// 从环境变量获取 WebSocket 主机地址
		// const wsHost = import.meta.env.VITE_WS_HOST || '18.167.251.121:10094'
		const wsHost = 'www.develop-ms.api.aida.com.hk'

		this.url = `${protocol}//${wsHost}/ws?token=${token}`
		this.isManualClose = false

		console.log('WebSocket 开始连接:', this.url.replace(/token=.+/, 'token=***'))

		try {
			this.ws = new WebSocket(this.url)
			this.initEventHandlers()
		} catch (error) {
			console.error('WebSocket 连接失败:', error)
			this.reconnect(token)
		}
	}

	/**
	 * 初始化事件处理器
	 */
	private initEventHandlers() {
		if (!this.ws) return

		this.ws.onopen = () => {
			console.log('✅ WebSocket 连接成功')
			this.reconnectAttempts = 0
			this.startHeartbeat()
		}

		this.ws.onmessage = (event) => {
			console.log('📨 WebSocket 收到消息:', event.data)
			try {
				const data = JSON.parse(event.data)
				this.handleMessage(data)
			} catch (error) {
				console.error('WebSocket 消息解析失败:', error)
			}
		}

		this.ws.onerror = (error) => {
			console.error('❌ WebSocket 错误:', error)
			console.error('可能的原因:')
			console.error('1. 服务器未运行或地址错误')
			console.error('2. Token 无效或已过期')
			console.error('3. 网络连接问题')
			console.error('4. 服务器拒绝连接')
		}

		this.ws.onclose = (event) => {
			const closeReasons: Record<number, string> = {
				1000: '正常关闭',
				1001: '端点离开',
				1002: '协议错误',
				1003: '不支持的数据类型',
				1006: '连接异常关闭（可能是网络问题或服务器未响应）',
				1007: '数据格式错误',
				1008: '违反策略',
				1009: '消息过大',
				1010: '扩展协商失败',
				1011: '服务器错误',
				1015: 'TLS 握手失败'
			}

			const reason = closeReasons[event.code] || '未知原因'
			console.log(`🔌 WebSocket 连接关闭 [代码: ${event.code}] ${reason}`)
			if (event.reason) {
				console.log('关闭原因:', event.reason)
			}

			this.stopHeartbeat()

			// 如果是异常关闭（非正常关闭码），才尝试重连
			if (!this.isManualClose && event.code !== 1000) {
				const token = this.extractTokenFromUrl()
				if (token) {
					this.reconnect(token)
				}
			} else if (event.code === 1000) {
				console.log('连接正常关闭，不进行重连')
			}
		}
	}

	/**
	 * 处理接收到的消息
	 * @param data 消息数据
	 */
	private handleMessage(data: any) {
		// 这里可以根据消息类型进行不同的处理
		// 例如：通知、消息推送等
		if (data.type === 'unread') {
			// 处理通知消息
			const info = data.data
			// console.log('收到通知-----:', info)
			useGlobalStore().setUnredCount(info.unreadCount)
			// 可以触发自定义事件或调用回调函数
		} 
	}

	/**
	 * 发送消息
	 * @param data 要发送的数据
	 */
	send(data: any) {
		if (this.ws && this.ws.readyState === WebSocket.OPEN) {
			const message = typeof data === 'string' ? data : JSON.stringify(data)
			this.ws.send(message)
		} else {
			console.warn('WebSocket 未连接，无法发送消息')
		}
	}

	/**
	 * 重连
	 * @param token 用户 token
	 */
	private reconnect(token: string) {
		if (this.reconnectAttempts >= this.maxReconnectAttempts) {
			console.error('❌ WebSocket 重连次数已达上限，停止重连')
			console.error('请检查:')
			console.error('1. 服务器是否正常运行')
			console.error('2. Token 是否有效')
			console.error('3. 网络连接是否正常')
			return
		}

		if (this.reconnectTimer) {
			clearTimeout(this.reconnectTimer)
		}

		this.reconnectAttempts++
		const delay = this.reconnectInterval * this.reconnectAttempts // 递增延迟
		console.log(
			`🔄 WebSocket 将在 ${delay / 1000} 秒后尝试重连 (${this.reconnectAttempts}/${
				this.maxReconnectAttempts
			})`
		)

		this.reconnectTimer = window.setTimeout(() => {
			this.connect(token)
		}, delay)
	}

	/**
	 * 开始心跳
	 */
	private startHeartbeat() {
		this.stopHeartbeat()
		this.heartbeatTimer = window.setInterval(() => {
			this.send({ type: 'heartbeat', timestamp: Date.now() })
		}, this.heartbeatInterval)
	}

	/**
	 * 停止心跳
	 */
	private stopHeartbeat() {
		if (this.heartbeatTimer) {
			clearInterval(this.heartbeatTimer)
			this.heartbeatTimer = null
		}
	}

	/**
	 * 从 URL 中提取 token
	 */
	private extractTokenFromUrl(): string | null {
		if (!this.url) return null
		const match = this.url.match(/token=([^&]+)/)
		return match ? match[1] : null
	}

	/**
	 * 关闭连接
	 */
	close() {
		this.isManualClose = true
		this.stopHeartbeat()

		if (this.reconnectTimer) {
			clearTimeout(this.reconnectTimer)
			this.reconnectTimer = null
		}

		if (this.ws) {
			this.ws.close()
			this.ws = null
		}

		console.log('WebSocket 已手动关闭')
	}

	/**
	 * 获取连接状态
	 */
	getReadyState(): number {
		return this.ws ? this.ws.readyState : WebSocket.CLOSED
	}

	/**
	 * 是否已连接
	 */
	isConnected(): boolean {
		return this.ws !== null && this.ws.readyState === WebSocket.OPEN
	}
}

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