// WebSocket 消息接口

import { WSMessage, WSMessageParams, MessageType } from './type';

export class WebSocketClient {
	private ws: WebSocket | null = null;
	private url: string;
	private currentRoom: string | null = null;
	private messageHandler: ((message: WSMessage) => void) | null = null;
	private connectionPromise: Promise<void> | null = null;

	constructor(url: string = 'ws://localhost:3000/ws') {
		this.url = url;
	}

	private async ensureConnected(): Promise<void> {
		if (this.ws?.readyState === WebSocket.OPEN) {
			return;
		}

		if (this.connectionPromise) {
			return this.connectionPromise;
		}

		this.connectionPromise = new Promise((resolve, reject) => {
			this.disconnect(); // 确保先断开旧连接

			this.ws = new WebSocket(this.url);

			this.ws.onopen = () => {
				console.log('WebSocket 连接已建立');
				this.connectionPromise = null;
				resolve();
			};

			this.ws.onmessage = (event) => {
				try {
					const message = JSON.parse(event.data) as WSMessage;

					// 处理所有系统消息、错误消息，以及当前房间的所有消息
					if (
						message.action === 'system' ||
						message.action === 'error' ||
						(message.action === 'message' && message.roomId === this.currentRoom)
					) {
						console.log('收到消息:', message);
						// 触发消息处理器
						if (this.messageHandler) {
							this.messageHandler(message);
						}
					}
				} catch (error) {
					console.error('解析消息失败:', error);
				}
			};

			this.ws.onclose = () => {
				console.log('WebSocket 连接已关闭');
				this.cleanup();
				reject(new Error('WebSocket connection closed'));
			};

			this.ws.onerror = (error) => {
				console.error('WebSocket 错误:', error);
				this.cleanup();
				reject(error);
			};

			// 5秒超时
			setTimeout(() => {
				if (this.ws?.readyState !== WebSocket.OPEN) {
					this.cleanup();
					reject(new Error('WebSocket connection timeout'));
				}
			}, 5000);
		});

		return this.connectionPromise;
	}

	async connect() {
		return this.ensureConnected();
	}

	private cleanup() {
		if (this.ws) {
			this.ws.onclose = null;
			this.ws.onerror = null;
			this.ws.onmessage = null;
			this.ws.onopen = null;
			this.ws = null;
		}
		this.currentRoom = null;
		this.messageHandler = null;
		this.connectionPromise = null;
	}

	// 设置消息处理器
	onMessage(handler: (message: WSMessage) => void) {
		this.messageHandler = handler;
		return () => {
			if (this.messageHandler === handler) {
				this.messageHandler = null;
			}
		};
	}

	async joinRoom(roomId: string) {
		try {
			await this.ensureConnected();

			// 如果已经在一个房间中，先离开
			if (this.currentRoom) {
				await this.leaveRoom();
			}

			const message: WSMessage = {
				action: 'join',
				roomId,
				data: {
					text: `加入房间 ${roomId}`,
					type: MessageType.TEXT,
				},
			};
			this.ws!.send(JSON.stringify(message));
			this.currentRoom = roomId;
		} catch (error) {
			console.error('加入房间失败:', error);
			throw error;
		}
	}

	async leaveRoom() {
		if (this.ws?.readyState === WebSocket.OPEN && this.currentRoom) {
			const message: WSMessage = {
				action: 'leave',
				roomId: this.currentRoom,
				data: {
					text: `离开房间 ${this.currentRoom}`,
					type: MessageType.TEXT,
				},
			};
			this.ws.send(JSON.stringify(message));
			this.currentRoom = null;
		}
	}

	async sendMessage(messageParams: WSMessageParams) {
		try {
			await this.ensureConnected();

			if (!this.currentRoom) {
				throw new Error('请先加入房间');
			}

			const messageObj: WSMessage = {
				action: 'message',
				roomId: this.currentRoom,
				data: {
					text: messageParams.text || '',
					type: messageParams.type || MessageType.TEXT,
					fileUri: messageParams.fileUri,
				},
			};
			this.ws!.send(JSON.stringify(messageObj));
		} catch (error) {
			console.error('发送消息失败:', error);
			throw error;
		}
	}

	disconnect() {
		if (this.currentRoom) {
			this.leaveRoom();
		}
		if (this.ws && this.ws.readyState === WebSocket.OPEN) {
			this.ws.close();
		}
		this.cleanup();
	}

	getCurrentRoom() {
		return this.currentRoom;
	}

	isConnected() {
		return this.ws?.readyState === WebSocket.OPEN;
	}
}

// 导出一个默认的 WebSocket 客户端实例
export const wsClient = new WebSocketClient();
