import { createBunWebSocket } from 'hono/bun';
import type { ServerWebSocket } from 'bun';
import { WSContext } from 'hono/ws';
enum MessageType {
	TEXT = 'text',
	IMAGE = 'image',
	FILE = 'file',
	RETRACT = 'retract', // 用于实现撤回
}
interface WSMessageParams {
	text?: string;
	type?: MessageType;
	fileUri?: string;
}
// 定义消息类型接口
interface WSMessage {
	action: 'join' | 'leave' | 'message';
	roomId: string;
	data: WSMessageParams;
}

// 创建 WebSocket 实例并指定泛型类型
const { upgradeWebSocket, websocket } = createBunWebSocket<ServerWebSocket>();

// 存储房间和连接的映射关系
const rooms = new Map<string, Set<WSContext<ServerWebSocket>>>();

// WebSocket 处理器
const wsHandler = upgradeWebSocket((c) => {
	// 存储当前连接加入的房间
	const joinedRooms = new Set<string>();

	return {
		onOpen(_, ws) {
			console.log('WebSocket 连接已建立');
		},
		onMessage(message, ws) {
			try {
				const parsedMessage: WSMessage = JSON.parse(message.data as any);
				console.log('收到消息:', parsedMessage);

				switch (parsedMessage.action) {
					case 'join':
						// 加入房间
						if (!rooms.has(parsedMessage.roomId)) {
							rooms.set(parsedMessage.roomId, new Set());
						}
						rooms.get(parsedMessage.roomId)?.add(ws);
						joinedRooms.add(parsedMessage.roomId);

						// 发送加入成功消息
						ws.send(
							JSON.stringify({
								action: 'system',
								data: {
									text: `成功加入房间 ${parsedMessage.roomId}`,
									type: MessageType.TEXT,
								},
								roomId: parsedMessage.roomId,
							}),
						);
						break;

					case 'leave':
						// 离开房间
						rooms.get(parsedMessage.roomId)?.delete(ws);
						joinedRooms.delete(parsedMessage.roomId);
						if (rooms.get(parsedMessage.roomId)?.size === 0) {
							rooms.delete(parsedMessage.roomId);
						}
						break;

					case 'message':
						// 在指定房间内广播消息
						const room = rooms.get(parsedMessage.roomId);
						if (room) {
							const messageToSend = {
								action: 'message',
								data: parsedMessage.data,
								roomId: parsedMessage.roomId,
							};

							for (const conn of room) {
								if (conn.readyState === WebSocket.OPEN) {
									conn.send(JSON.stringify(messageToSend));
								}
							}
						}
						break;
				}
			} catch (error) {
				console.error('处理消息时出错:', error);
				ws.send(
					JSON.stringify({
						action: 'error',
						data: {
							text: '消息处理失败',
							type: MessageType.TEXT,
						},
					}),
				);
			}
		},
		onClose(_, ws) {
			console.log('WebSocket 连接已关闭');
			// 清理所有加入的房间
			for (const roomId of joinedRooms) {
				rooms.get(roomId)?.delete(ws);
				if (rooms.get(roomId)?.size === 0) {
					rooms.delete(roomId);
				}
			}
		},
		onError(error, ws) {
			console.error('WebSocket 错误:', error);
			// 清理所有加入的房间
			for (const roomId of joinedRooms) {
				rooms.get(roomId)?.delete(ws);
				if (rooms.get(roomId)?.size === 0) {
					rooms.delete(roomId);
				}
			}
		},
	};
});

export const wsConfig = {
	websocket,
};

export { wsHandler, rooms };
