import { Window } from '../core/windows.js';
import { API, STORAGE_KEYS, CSS } from '../core/config.js';
import { eventBus, Events } from '../core/events.js';

export class GameRoomWindow extends Window {
	constructor() {
		super({
			name: 'gameroom',
			title: 'Game Rooms',
			cssClasses: ['gameroom-window']
		});

		this.currentTab = 'browse';
		this.currentRoom = null;
		this.roomsList = [];
		this.socket = null;
		this.isSpectating = false;
		this.messageTimeout = null;
		this.buildUI();
		this.bindEvents();

		// Handle page close/refresh to disconnect socket
		window.addEventListener('beforeunload', () => {
			if (this.socket?.connected) {
				this.socket.disconnect();
			}
		});
		eventBus.on(Events.USER_LOGGED_IN, () => {
			this.updateTabsAccess();
			this.checkCurrentRoom();
		});
		eventBus.on(Events.USER_LOGGED_OUT, () => {
			this.handleLogout();
		});

		this.updateTabsAccess();

		// Verifier si l'utilisateur est deja dans un salon au chargement
		const token = localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
		if (token)
			this.checkCurrentRoom();
	}

	buildUI() {
		this.tabs = this.createElement('div', CSS.GAMEROOM_TABS);

		this.browseTab = this.createElement('button', [CSS.GAMEROOM_TAB, CSS.GAMEROOM_TAB_ACTIVE], {
			text: 'Salons'
		});
		this.browseTab.dataset.tab = 'browse';

		this.spectatorTab = this.createElement('button', CSS.GAMEROOM_TAB, {
			text: 'Spectateur'
		});
		this.spectatorTab.dataset.tab = 'spectator';

		this.createTab = this.createElement('button', CSS.GAMEROOM_TAB, {
			text: 'Creer'
		});
		this.createTab.dataset.tab = 'create';

		this.lobbyTab = this.createElement('button', CSS.GAMEROOM_TAB, {
			text: 'Lobby'
		});
		this.lobbyTab.dataset.tab = 'lobby';
		this.lobbyTab.style.display = 'none';

		this.tabs.append(this.browseTab, this.spectatorTab, this.createTab, this.lobbyTab);

		this.content = this.createElement('div', CSS.GAMEROOM_CONTENT);

		this.createContainer = this.createElement('div', CSS.GAMEROOM_CREATE);
		this.roomNameInput = this.createElement('input', CSS.INPUT, {
			type: 'text',
			placeholder: 'Nom du salon...'
		});
		this.createBtn = this.createElement('button', [CSS.BTN, CSS.BTN_PRIMARY], {
			text: 'Creer le salon'
		});
		this.createContainer.append(this.roomNameInput, this.createBtn);
		this.createContainer.style.display = 'none';

		this.lobbyContainer = this.createElement('div', CSS.GAMEROOM_LOBBY);
		this.lobbyTitle = this.createElement('h3', 'gameroom__lobby-title', { text: '' });
		this.playerList = this.createElement('div', CSS.GAMEROOM_PLAYER_LIST);

		// Boutons du lobby
		this.lobbyButtons = this.createElement('div', 'gameroom__lobby-buttons');
		this.startGameBtn = this.createElement('button', [CSS.BTN, CSS.BTN_SUCCESS], {
			text: 'Lancer le jeu'
		});
		this.leaveBtn = this.createElement('button', [CSS.BTN, CSS.BTN_DANGER], {
			text: 'Quitter'
		});
		this.lobbyButtons.append(this.startGameBtn, this.leaveBtn);

		// Container du jeu (caché par défaut)
		this.gameContainer = this.createElement('div', 'gameroom__game');
		this.gameContainer.style.display = 'none';
		this.buildGameUI();

		this.lobbyContainer.append(this.lobbyTitle, this.playerList, this.lobbyButtons, this.gameContainer);
		this.lobbyContainer.style.display = 'none';

		this.list = this.createElement('div', CSS.GAMEROOM_LIST);

		this.spectatorList = this.createElement('div', CSS.GAMEROOM_LIST);
		this.spectatorList.style.display = 'none';

		this.message = this.createElement('div', CSS.MESSAGE);

		this.content.append(this.createContainer, this.lobbyContainer, this.list, this.spectatorList, this.message);

		this.body.append(this.tabs, this.content);
	}

	buildGameUI() {
		// Zone d'info du jeu
		this.gameInfo = this.createElement('div', 'gameroom__game-info');
		this.currentDrawerInfo = this.createElement('div', 'gameroom__drawer-info', { text: '' });
		this.scoresDisplay = this.createElement('div', 'gameroom__scores-display');
		this.gameInfo.append(this.currentDrawerInfo, this.scoresDisplay);

		// Affichage du mot caché
		this.wordDisplay = this.createElement('div', 'gameroom__word-display');

		// Canvas de dessin
		this.canvasContainer = this.createElement('div', 'gameroom__canvas-container');
		this.canvas = document.createElement('canvas');
		this.canvas.className = 'gameroom__canvas';
		this.canvas.width = 380;
		this.canvas.height = 200;
		this.ctx = this.canvas.getContext('2d');
		this.canvasContainer.appendChild(this.canvas);

		// Outils de dessin
		this.drawTools = this.createElement('div', 'gameroom__draw-tools');
		this.colorPicker = this.createElement('input', 'gameroom__color-picker');
		this.colorPicker.type = 'color';
		this.colorPicker.value = '#ffffff';
		this.clearCanvasBtn = this.createElement('button', [CSS.BTN, CSS.BTN_SECONDARY], { text: 'Effacer' });
		this.drawTools.append(this.colorPicker, this.clearCanvasBtn);
		this.drawTools.style.display = 'none';

		// Zone pour choisir le mot (pour le dessinateur)
		this.wordInputContainer = this.createElement('div', 'gameroom__word-input-container');
		this.wordInput = this.createElement('input', CSS.INPUT, {
			type: 'text',
			placeholder: 'Entrez le mot a faire deviner...'
		});
		this.confirmWordBtn = this.createElement('button', [CSS.BTN, CSS.BTN_PRIMARY], { text: 'OK' });
		this.wordInputContainer.append(this.wordInput, this.confirmWordBtn);
		this.wordInputContainer.style.display = 'none';

		// Zone pour deviner (pour les autres joueurs)
		this.guessContainer = this.createElement('div', 'gameroom__guess-container');
		this.letterInput = this.createElement('input', CSS.INPUT, {
			type: 'text',
			placeholder: 'Proposez une lettre ou le mot...',
			maxLength: '50'
		});
		this.guessBtn = this.createElement('button', [CSS.BTN, CSS.BTN_PRIMARY], { text: 'Deviner' });
		this.guessContainer.append(this.letterInput, this.guessBtn);
		this.guessContainer.style.display = 'none';

		// Historique des tentatives
		this.guessHistory = this.createElement('div', 'gameroom__guess-history');

		// Boutons du jeu
		this.gameButtons = this.createElement('div', 'gameroom__game-buttons');
		this.backToLobbyBtn = this.createElement('button', [CSS.BTN, CSS.BTN_SECONDARY], { text: 'Quitter la partie' });
		this.endRoundBtn = this.createElement('button', [CSS.BTN, CSS.BTN_DANGER], { text: 'Terminer le jeu' });
		this.gameButtons.append(this.backToLobbyBtn, this.endRoundBtn);

		this.gameContainer.append(
			this.gameInfo,
			this.wordDisplay,
			this.canvasContainer,
			this.drawTools,
			this.wordInputContainer,
			this.guessContainer,
			this.guessHistory,
			this.gameButtons
		);

		// Initialiser les variables du jeu
		this.gameState = {
			isPlaying: false,
			currentWord: '',
			wordLength: 0,
			revealedLetters: [],
			revealedWord: [],
			drawer: null,
			players: [],
			currentPlayerIndex: 0,
			guessedLetters: [],
			scores: {},
			counter: 0,
			counterRound: 0
		};

		this.initDrawing();
	}

	initDrawing() {
		this.isDrawing = false;
		this.lastX = 0;
		this.lastY = 0;

		this.canvas.addEventListener('mousedown', (e) => {
			if (!this.gameState.isPlaying || !this.isCurrentUserDrawer() || this.isSpectating) return;
			this.isDrawing = true;
			[this.lastX, this.lastY] = [e.offsetX, e.offsetY];
		});

		this.canvas.addEventListener('mousemove', (e) => {
			if (!this.isDrawing) return;

			const x1 = this.lastX;
			const y1 = this.lastY;
			const x2 = e.offsetX;
			const y2 = e.offsetY;
			const color = this.colorPicker.value;
			const lineWidth = 3;

			// Dessiner localement
			this.drawLine(x1, y1, x2, y2, color, lineWidth);

			// Envoyer aux autres joueurs via WebSocket
			if (this.socket?.connected) {
				this.socket.emit('game-draw', { x1, y1, x2, y2, color, lineWidth });
			}

			[this.lastX, this.lastY] = [x2, y2];
		});

		this.canvas.addEventListener('mouseup', () => this.isDrawing = false);
		this.canvas.addEventListener('mouseout', () => this.isDrawing = false);

		this.clearCanvasBtn.addEventListener('click', () => {
			this.clearCanvas();
			// Notifier les autres
			if (this.socket?.connected) {
				this.socket.emit('game-clear-canvas');
			}
		});
	}

	drawLine(x1, y1, x2, y2, color, lineWidth) {
		this.ctx.beginPath();
		this.ctx.strokeStyle = color;
		this.ctx.lineWidth = lineWidth;
		this.ctx.lineCap = 'round';
		this.ctx.moveTo(x1, y1);
		this.ctx.lineTo(x2, y2);
		this.ctx.stroke();
	}

	clearCanvas() {
		this.ctx.fillStyle = '#333';
		this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
	}

	bindEvents() {
		this.tabs.addEventListener('click', (e) => {
			const tab = e.target.closest(`.${CSS.GAMEROOM_TAB}`);
			if (tab) {
				this.switchTab(tab.dataset.tab);
			}
		});

		this.createBtn.addEventListener('click', () => this.createRoom());
		this.roomNameInput.addEventListener('keypress', (e) => {
			if (e.key === 'Enter') this.createRoom();
		});

		this.leaveBtn.addEventListener('click', () => this.leaveRoom());
		this.startGameBtn.addEventListener('click', () => this.startGame());

		// Events du jeu
		this.confirmWordBtn.addEventListener('click', () => this.confirmWord());
		this.wordInput.addEventListener('keypress', (e) => {
			if (e.key === 'Enter') this.confirmWord();
		});

		this.guessBtn.addEventListener('click', () => this.makeGuess());
		this.letterInput.addEventListener('keypress', (e) => {
			if (e.key === 'Enter') this.makeGuess();
		});

		this.backToLobbyBtn.addEventListener('click', () => this.backToLobby());
		this.endRoundBtn.addEventListener('click', () => this.endGame());
	}

	// ============================================
	// SOCKET.IO CONNECTION
	// ============================================

	async connectToGameSocket() {
		const token = localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
		if (!token || !this.currentRoom) return;

		// Ensure socket is connected
		await this.ensureSocketConnected();

		// Join the room
		if (this.socket?.connected) {
			console.log('Socket connected, joining room:', this.currentRoom.id);
			this.socket.emit('game-join-room', { roomId: this.currentRoom.id });
		}
	}

	async loadSocketIO() {
		if (window.io) return;

		return new Promise((resolve, reject) => {
			const script = document.createElement('script');
			script.src = '/socket.io/socket.io.js';

			script.onload = () => {
				console.log('Socket.IO loaded for game');
				resolve();
			};

			script.onerror = () => {
				console.error('Failed to load Socket.IO');
				reject(new Error('Socket.IO load failed'));
			};

			document.head.appendChild(script);
		});
	}

	setupGameSocketListeners() {
		this.socketReady = false;

		this.socket.on('connect', () => {
			console.log('Game socket connected, id:', this.socket.id);
			if (this.currentRoom) {
				console.log('Joining room:', this.currentRoom.id);
				this.socket.emit('game-join-room', { roomId: this.currentRoom.id });
			}
		});

		this.socket.on('connect_error', (err) => {
			console.error('Game socket connection error:', err.message);
		});

		// Confirmation that we joined the room
		this.socket.on('game-room-joined', (data) => {
			console.log('Successfully joined game room:', data.roomId);
			this.socketReady = true;
		});

		// Real-time rooms list update
		this.socket.on('game-rooms-updated', (data) => {
			console.log('Rooms list updated:', data.rooms?.length, 'rooms');
			if (this.currentTab === 'browse') {
				this.roomsList = data.rooms || [];
				this.renderRoomsList(this.roomsList);
			}
		});

		// Real-time player list update in lobby
		this.socket.on('game-players-updated', (data) => {
			console.log('Players list updated:', data.players?.length, 'players');
			if (this.currentRoom) {
				this.renderPlayersList(data.players || []);
			}
		});

		// Player joined/left
		this.socket.on('game-player-joined', (data) => {
			console.log(`${data.username} joined the room`);
		});

		this.socket.on('game-player-left', (data) => {
			this.showMessage(`${data.username} a quitté le salon`, 'info');
			console.log(`${data.username} left the room`);

			if (this.gameState.isPlaying)
			{
				if (Array.isArray(this.gameState.players))
					this.gameState.players = this.gameState.players.filter(p => p !== data.username);
			}

			if (this.gameState.scores)
			{
				delete this.gameState.scores[data.username];
				this.updateScoresDisplay(this.gameState.scores);
			}

			// Note: If the drawer left, the server will emit 'game-drawer-changed' 
			// with the new drawer, so we don't need to handle it here

			if (this.currentRoom && !this.gameState.isPlaying)
				this.loadLobby();
		});

		// Game started
		this.socket.on('game-started', (data) => {
			console.log('Received game-started event:', data);
			this.gameState.isPlaying = true;
			this.gameState.drawer = data.drawer;
			this.gameState.players = data.players;
			this.gameState.currentPlayerIndex = data.players.indexOf(data.drawer);

			// Initialize scores
			this.gameState.scores = {};
			data.players.forEach(p => this.gameState.scores[p] = 0);

			this.showGameUI();
			this.setupRound();
		});

		// Game start error
		this.socket.on('game-start-error', (data) => {
			console.error('Game start error:', data.error);
			this.showMessage(data.error || 'Impossible de démarrer la partie', 'error');
		});

		// Word was set by drawer
		this.socket.on('game-word-set', (data) => {
			console.log(`Word set by ${data.drawer}, length: ${data.wordLength}`);
			this.gameState.wordLength = data.wordLength;
			this.gameState.revealedLetters = new Array(data.wordLength).fill(false);
			this.gameState.revealedWord = data.revealedWord || new Array(data.wordLength).fill('_');

			if (data.scores) {
				this.updateScoresDisplay(data.scores);
			}

			this.updateWordDisplay();
			
			// Don't change UI for spectators
			if (this.isSpectating) {
				this.currentDrawerInfo.textContent = '👁️ MODE SPECTATEUR - Vous regardez la partie';
				return;
			}
			
			this.currentDrawerInfo.textContent = `${data.drawer} dessine (${data.wordLength} lettres)`;

			// Enable guess input for non-drawers
			if (!this.isCurrentUserDrawer()) {
				this.guessContainer.style.display = 'flex';
				this.letterInput.disabled = false;
				this.guessBtn.disabled = false;
				this.letterInput.placeholder = 'Proposez une lettre ou le mot...';
				this.letterInput.focus();
			}
		});

		// Drawing received
		this.socket.on('game-draw', (data) => {
			this.drawLine(data.x1, data.y1, data.x2, data.y2, data.color, data.lineWidth);
		});

		// Clear canvas
		this.socket.on('game-clear-canvas', () => {
			this.clearCanvas();
		});

		// Guess result
		this.socket.on('game-guess-result', (data) => {
			this.addGuessToHistory(data.guess, data.success, data.type, data.username, data.points || 0);

			if (data.revealedLetters) {
				this.gameState.revealedLetters = data.revealedLetters;
			}
			if (data.revealedWord) {
				this.gameState.revealedWord = data.revealedWord;
			}
			if (data.scores) {
				this.updateScoresDisplay(data.scores);
			}
			this.updateWordDisplay();
		});

		// Word found
		this.socket.on('game-word-found', (data) => {
			if (data.scores) {
				this.updateScoresDisplay(data.scores);
			}
			this.wordFound(data.word, data.winner, data.drawerBonus || 0);
		});

		// New round
		this.socket.on('game-new-round', (data) => {
			this.gameState.drawer = data.drawer;
			this.gameState.currentPlayerIndex = this.gameState.players.indexOf(data.drawer);
			this.setupRound();
		});

		// Game ended
		this.socket.on('game-ended', () => {
			// If spectating, return to spectator list
			if (this.isSpectating) {
				this.resetGameUI();
				// this.currentRoom = null;
				this.isSpectating = false;
				this.switchTab('spectator');
				this.showMessage('La partie est terminée', 'info');
			} else {
				this.resetGameUI();
				this.loadLobby();
			}
		});

		// Game message from server
		this.socket.on('game-message', (data) => {
			this.showMessage(data.message, data.type || 'info');
		});

		// Sync state for late joiners
		this.socket.on('game-state-sync', (data) => {
			if (data.isPlaying) {
				this.gameState.isPlaying = true;
				this.gameState.drawer = data.drawer;
				this.gameState.wordLength = data.wordLength;
				this.gameState.revealedLetters = data.revealedLetters || [];
				this.gameState.revealedWord = data.revealedWord || new Array(data.wordLength).fill('_');
				this.gameState.players = data.players;
				this.gameState.scores = data.scores || {};

				this.showGameUI();
				this.updateWordDisplay();

				// Update scores display
				if (data.scores) {
					this.updateScoresDisplay(data.scores);
				}

				this.currentDrawerInfo.textContent = `${data.drawer} dessine (${data.wordLength} lettres)`;

				// Don't enable input for spectators
				if (this.isSpectating) {
					this.guessContainer.style.display = 'none';
					this.wordInputContainer.style.display = 'none';
					this.drawTools.style.display = 'none';
					this.currentDrawerInfo.textContent = '👁️ MODE SPECTATEUR - Vous regardez la partie';
				} else if (!this.isCurrentUserDrawer()) {
					this.guessContainer.style.display = 'flex';
					if (data.wordLength > 0) {
						this.letterInput.disabled = false;
						this.guessBtn.disabled = false;
						this.letterInput.placeholder = 'Proposez une lettre ou le mot...';
					} else {
						this.letterInput.disabled = true;
						this.guessBtn.disabled = true;
						this.letterInput.placeholder = 'En attente du mot...';
					}
				}
			}
		});

		// Spectator events
		this.socket.on('game-spectate-joined', (data) => {
			console.log('Successfully joined as spectator:', data.roomId);
			this.isSpectating = true;
			
			// Prepare UI for spectating
			this.spectatorList.style.display = 'none';
			this.list.style.display = 'none';
			this.createContainer.style.display = 'none';
			this.lobbyContainer.style.display = 'flex';
			
			// Hide lobby elements, keep game container for when state syncs
			this.playerList.style.display = 'none';
			this.lobbyButtons.style.display = 'none';
			this.lobbyTitle.textContent = 'Mode Spectateur';
			
			this.showMessage('Vous regardez la partie...', 'success');
			// The game state will be synced via game-state-sync event
		});

		this.socket.on('game-spectate-error', (data) => {
			console.error('Spectate error:', data.error);
			this.showMessage(data.error || 'Impossible de regarder cette partie', 'error');
		});

		this.socket.on('game-spectator-joined', (data) => {
			console.log(`Spectator ${data.username} joined`);
		});

		this.socket.on('game-spectator-left', (data) => {
			console.log(`Spectator ${data.username} left`);
		});

		// Drawer changed (when drawer leaves during game)
		this.socket.on('game-drawer-changed', (data) => {
			console.log('Drawer changed:', data);
			this.showMessage(data.message, 'info');

			// Update game state with new drawer
			this.gameState.drawer = data.newDrawer;
			this.gameState.currentPlayerIndex = this.gameState.players.indexOf(data.newDrawer);

			// Reset round state
			this.gameState.currentWord = '';
			this.gameState.wordLength = 0;
			this.gameState.revealedLetters = [];
			this.gameState.revealedWord = [];
			this.gameState.guessedLetters = [];

			// Clear canvas and history
			this.clearCanvas();
			this.guessHistory.innerHTML = '';
			this.wordDisplay.textContent = '';

			// Setup UI for new round with new drawer
			this.setupRound();
		});
	}

	disconnectGameSocket() {
		if (this.socket) {
			if (this.isSpectating) {
				this.socket.emit('game-leave-spectate');
			} else {
				this.socket.emit('game-leave-room');
			}
		}
	}

	// ============================================
	// UI HELPERS
	// ============================================

	isLoggedIn() {
		return !!localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
	}

	updateTabsAccess() {
		const loggedIn = this.isLoggedIn();

		this.createTab.disabled = !loggedIn;
		this.createTab.style.opacity = loggedIn ? '1' : '0.5';
		this.createTab.title = loggedIn ? '' : 'Connectez-vous pour creer un salon';

		if (!loggedIn && this.currentTab === 'create') {
			this.switchTab('browse');
		}
	}

	handleLogout() {
		this.disconnectGameSocket();
		if (this.currentRoom) {
			this.exitLobby();
		}
		this.updateTabsAccess();
		if (this.currentTab !== 'browse') {
			this.switchTab('browse');
		}
	}

	switchTab(tabName) {
		if (tabName === 'lobby' && !this.currentRoom) {
			return;
		}

		if (tabName === 'create' && !this.isLoggedIn()) {
			this.showMessage('Connectez-vous pour creer un salon', 'info');
			return;
		}

		this.currentTab = tabName;

		[this.browseTab, this.spectatorTab, this.createTab, this.lobbyTab].forEach(tab => {
			tab.classList.toggle(CSS.GAMEROOM_TAB_ACTIVE, tab.dataset.tab === tabName);
		});

		this.createContainer.style.display = tabName === 'create' ? 'flex' : 'none';
		this.lobbyContainer.style.display = tabName === 'lobby' ? 'flex' : 'none';
		this.list.style.display = tabName === 'browse' ? 'flex' : 'none';
		this.spectatorList.style.display = tabName === 'spectator' ? 'flex' : 'none';

		this.loadCurrentTab();
	}

	loadCurrentTab() {
		switch (this.currentTab) {
			case 'browse':
				this.loadRooms();
				// Connect to socket to receive real-time room updates
				this.ensureSocketConnected();
				break;
			case 'spectator':
				this.loadPlayingRooms();
				this.ensureSocketConnected();
				break;
			case 'create':
				this.message.textContent = '';
				this.ensureSocketConnected();
				break;
			case 'lobby':
				if (this.currentRoom) {
					this.loadLobby();
				}
				break;
		}
	}

	async ensureSocketConnected() {
		if (!this.isLoggedIn()) return;
		if (this.socket?.connected) return;

		const token = localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
		if (!token) return;

		await this.loadSocketIO();

		const ioConfig = {
			auth: { token },
			reconnection: true,
			reconnectionAttempts: 5,
			reconnectionDelay: 1000,
			transports: ['websocket', 'polling']
		};

		const altPort = window.GLOBAL_CHAT_ALT_PORT;
		if (altPort) {
			const host = location.hostname || 'localhost';
			this.socket = io(`${location.protocol}//${host}:${altPort}`, ioConfig);
		} else {
			this.socket = io(ioConfig);
		}

		this.setupGameSocketListeners();
	}

	getHeaders() {
		const token = localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
		return {
			'Authorization': `Bearer ${token}`,
			'Content-Type': 'application/json'
		};
	}

	async loadRooms() {
		const token = localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
		if (!token) {
			this.showMessage('Connectez-vous pour voir les salons', 'info');
			return;
		}

		try {
			const response = await fetch(API.ROOMS.LIST, {
				headers: this.getHeaders()
			});
			const data = await response.json();

			if (!response.ok) {
				this.showMessage(data.error || 'Erreur', 'error');
				return;
			}

			this.renderRoomsList(data || []);
		} catch (error) {
			console.error('Load rooms error:', error);
			this.showMessage('Erreur de connexion', 'error');
		}
	}

	async checkCurrentRoom() {
		const token = localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
		if (!token) {
			return null;
		}

		try {
			const response = await fetch(API.ROOMS.CURRENT, {
				headers: this.getHeaders()
			});

			// 204 No Content means user is not in any room
			if (response.status === 204) {
				return null;
			}

			if (!response.ok) {
				return null;
			}

			const data = await response.json();
			if (data && data.id) {
				this.currentRoom = data;
				this.enterLobby(data);
				return data;
			}
			return null;
		} catch (error) {
			console.error('Check current room error:', error);
			return null;
		}
	}

	roomNameExists(name) {
		const normalizedName = name.toLowerCase().trim();
		return this.roomsList.some(room => room.name.toLowerCase().trim() === normalizedName);
	}

	renderRoomsList(rooms) {
		this.list.innerHTML = '';
		this.message.textContent = '';

		if (rooms.length === 0) {
			this.showMessage('Aucun salon disponible', 'info');
			return;
		}

		rooms.forEach(room => {
			const item = this.createRoomItem(room);
			this.list.appendChild(item);
		});
	}

	createRoomItem(room) {
		const item = this.createElement('div', CSS.GAMEROOM_ITEM);

		const name = this.createElement('span', CSS.GAMEROOM_NAME, {
			text: room.name
		});

		const players = this.createElement('span', CSS.GAMEROOM_PLAYERS, {
			text: `${room.player_count || 0}/${room.max_players || 8}`
		});

		const actions = this.createElement('div', CSS.GAMEROOM_ACTIONS);

		const joinBtn = this.createElement('button', [CSS.BTN, CSS.BTN_SUCCESS], {
			text: 'Rejoindre'
		});
		joinBtn.addEventListener('click', () => this.joinRoom(room.id));
		actions.appendChild(joinBtn);

		item.append(name, players, actions);
		return item;
	}

	async createRoom() {
		const name = this.roomNameInput.value.trim();
		if (!name) {
			this.showMessage('Entrez un nom pour le salon', 'error');
			this.showNotification('Entrez un nom pour le salon', 'red');
			return;
		}

		const token = localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
		if (!token) {
			this.showMessage('Connectez-vous pour creer un salon', 'info');
			this.showNotification('Connectez-vous pour créer un salon', 'red');
			return;
		}

		if (this.currentRoom) {
			this.showMessage('Vous etes deja dans un salon. Quittez-le d\'abord.', 'error');
			this.showNotification('Vous êtes déjà dans un salon. Quittez-le d\'abord.', 'red');
			return;
		}

		try {
			const currentResponse = await fetch(API.ROOMS.CURRENT, {
				headers: this.getHeaders()
			});
			if (currentResponse.ok && currentResponse.status !== 204) {
				const currentData = await currentResponse.json();
				if (currentData && currentData.id) {
					this.currentRoom = currentData;
					this.enterLobby(currentData);
					this.showMessage('Vous etes deja dans un salon', 'error');
					this.showNotification('Vous êtes déjà dans un salon. Quittez-le d\'abord.', 'red');
					return;
				}
			}
		} catch (e) {
			// Continue
		}

		try {
			const listResponse = await fetch(API.ROOMS.LIST, {
				headers: this.getHeaders()
			});
			if (listResponse.ok) {
				this.roomsList = await listResponse.json() || [];
			}
		} catch (e) {
			// Continue
		}

		if (this.roomNameExists(name)) {
			this.showMessage('Un salon avec ce nom existe deja', 'error');
			this.showNotification('Un salon avec ce nom existe deja', 'red');
			return;
		}

		try {
			const response = await fetch(API.ROOMS.CREATE, {
				method: 'POST',
				headers: this.getHeaders(),
				body: JSON.stringify({ name })
			});
			const data = await response.json();

			if (!response.ok) {
				this.showMessage(data.error || 'Erreur', 'error');
				return;
			}

			this.roomNameInput.value = '';
			this.currentRoom = data;
			this.showMessage('Salon cree', 'success');
			eventBus.emit(Events.ROOM_CREATED, data);
			this.enterLobby(data);
			this.showNotification(`Vous avez créé le salon "${data.name}"`, 'green');
		} catch (error) {
			console.error('Create room error:', error);
			this.showMessage('Erreur de connexion', 'error');
		}
	}

	createSpectatorRoomItem(room) {
		const item = this.createElement('div', CSS.GAMEROOM_ITEM);

		const name = this.createElement('span', CSS.GAMEROOM_NAME, {
			text: room.name
		});

		const players = this.createElement('span', CSS.GAMEROOM_PLAYERS, {
			text: `${room.player_count || 0}/${room.max_players || 8}`
		});

		const status = this.createElement('span', 'gameroom__status', {
			text: '🎮 En cours'
		});
		status.style.color = '#4CAF50';
		status.style.fontWeight = 'bold';

		const actions = this.createElement('div', CSS.GAMEROOM_ACTIONS);

		const spectateBtn = this.createElement('button', [CSS.BTN, CSS.BTN_PRIMARY], {
			text: 'Regarder'
		});
		spectateBtn.addEventListener('click', () => this.spectateRoom(room.id));
		actions.appendChild(spectateBtn);

		item.append(name, players, status, actions);
		return item;
	}

	async loadPlayingRooms() {
		const token = localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
		if (!token) {
			this.showMessage('Connectez-vous pour voir les parties en cours', 'info');
			return;
		}

		try {
			const response = await fetch(API.ROOMS.PLAYING, {
				headers: this.getHeaders()
			});
			const data = await response.json();

			if (!response.ok) {
				this.showMessage(data.error || 'Erreur', 'error');
				return;
			}

			this.renderPlayingRoomsList(data || []);
		} catch (error) {
			console.error('Load playing rooms error:', error);
			this.showMessage('Erreur de connexion', 'error');
		}
	}

	renderPlayingRoomsList(rooms) {
		this.spectatorList.innerHTML = '';
		this.message.textContent = '';

		if (rooms.length === 0) {
			this.showMessage('Aucune partie en cours', 'info');
			return;
		}

		rooms.forEach(room => {
			const item = this.createSpectatorRoomItem(room);
			this.spectatorList.appendChild(item);
		});
	}

	async spectateRoom(roomId) {
		const token = localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
		if (!token) {
			this.showMessage('Connectez-vous pour regarder', 'info');
			return;
		}

		// Check if user is already in a room as a player
		if (this.currentRoom && !this.isSpectating) {
			this.showMessage('Vous êtes déjà dans un salon. Quittez-le d\'abord.', 'error');
			return;
		}

		// Check if already spectating another game
		if (this.isSpectating && this.currentRoom && this.currentRoom.id !== roomId) {
			this.showMessage('Vous regardez déjà une autre partie', 'error');
			return;
		}

		try {
			const response = await fetch(API.ROOMS.SPECTATE(roomId), {
				method: 'POST',
				headers: this.getHeaders()
			});
			const data = await response.json();

			if (!response.ok) {
				this.showMessage(data.error || 'Impossible de regarder cette partie', 'error');
				return;
			}

			// Store room info and mark as spectating
			this.currentRoom = data;
			this.isSpectating = true;

			// Join as spectator via socket
			await this.ensureSocketConnected();
			if (this.socket?.connected) {
				this.socket.emit('game-spectate-room', { roomId: roomId });
			}

			this.showMessage('Connexion à la partie...', 'info');
		} catch (error) {
			console.error('Spectate room error:', error);
			this.showMessage('Erreur de connexion', 'error');
		}
	}

	async joinRoom(roomId) {
		const token = localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
		if (!token) {
			this.showMessage('Connectez-vous pour rejoindre', 'info');
			return;
		}

		if (this.currentRoom) {
			this.showMessage('Vous etes deja dans un salon. Quittez-le d\'abord.', 'error');
			this.showNotification('Vous êtes déjà dans un salon. Quittez-le d\'abord.', 'red');
			return;
		}

		try {
			const currentResponse = await fetch(API.ROOMS.CURRENT, {
				headers: this.getHeaders()
			});
			if (currentResponse.ok && currentResponse.status !== 204) {
				const currentData = await currentResponse.json();
				if (currentData && currentData.id) {
					this.currentRoom = currentData;
					this.enterLobby(currentData);
					this.showMessage('Vous etes deja dans un salon', 'error');
					this.showNotification('Vous êtes déjà dans un salon. Quittez-le d\'abord.', 'red');
					return;
				}
			}
		} catch (e) {
			// Continue
		}

		try {
			const response = await fetch(API.ROOMS.JOIN(roomId), {
				method: 'POST',
				headers: this.getHeaders()
			});
			const data = await response.json();

			if (!response.ok) {
				this.showMessage(data.error || 'Erreur', 'error');
				return;
			}

			const roomResponse = await fetch(API.ROOMS.GET(roomId), {
				headers: this.getHeaders()
			});
			const roomData = await roomResponse.json();

			this.currentRoom = roomData;
			eventBus.emit(Events.ROOM_JOINED, roomData);
			this.enterLobby(roomData);
		} catch (error) {
			console.error('Join room error:', error);
			this.showMessage('Erreur de connexion', 'error');
		}
	}

	enterLobby(room) {
		this.currentRoom = room;
		this.lobbyTab.style.display = 'block';
		this.lobbyTitle.textContent = room.name;
		this.switchTab('lobby');

		// Connect to WebSocket for real-time sync
		this.connectToGameSocket();
	}

	async loadLobby() {
		console.log('Loading lobby for room:', this.currentRoom);
		if (!this.currentRoom) return;
		console.log('Managed to load lobby, current room:', this.currentRoom);

		this.gameState.scores = {};

		try {
			const response = await fetch(API.ROOMS.PLAYERS(this.currentRoom.id), {
				headers: this.getHeaders()
			});
			const data = await response.json();

			if (!response.ok) {
				this.showMessage(data.error || 'Erreur', 'error');
				return;
			}

			this.renderPlayersList(data || []);
		} catch (error) {
			console.error('Load lobby error:', error);
			this.showMessage('Erreur de connexion', 'error');
		}
	}

	renderPlayersList(players) {
		this.playerList.innerHTML = '';

		if (players.length === 0) {
			const empty = this.createElement('div', 'gameroom__empty', {
				text: 'Aucun joueur'
			});
			this.playerList.appendChild(empty);
			// Disable start button if no players
			this.startGameBtn.disabled = true;
			this.startGameBtn.style.opacity = '0.5';
			this.startGameBtn.title = 'Il faut au moins 2 joueurs';
			return;
		}

		players.forEach(player => {
			const item = this.createElement('div', CSS.GAMEROOM_PLAYER);

			const avatar = this.createElement('img', CSS.GAMEROOM_PLAYER_AVATAR, {
				alt: player.username
			});
			avatar.src = player.avatar_url || '/avatar/default.png';

			const name = this.createElement('span', CSS.GAMEROOM_PLAYER_NAME, {
				text: player.username
			});

			const statsContainer = this.createElement('div', 'gameroom__player-stats');

			const score = this.createElement('span', CSS.GAMEROOM_PLAYER_SCORE, {
				text: `${player.score || 0} pts`
			});

			const totalPoints = this.createElement('span', 'gameroom__player-total', {
				text: `Total: ${player.total_points || 0}`
			});

			statsContainer.append(score, totalPoints);
			item.append(avatar, name, statsContainer);
			this.playerList.appendChild(item);
		});

		// Enable/disable start button based on player count
		if (players.length < 2) {
			this.startGameBtn.disabled = true;
			this.startGameBtn.style.opacity = '0.5';
			this.startGameBtn.title = 'Il faut au moins 2 joueurs';
		} else {
			this.startGameBtn.disabled = false;
			this.startGameBtn.style.opacity = '1';
			this.startGameBtn.title = '';
		}
	}

	async leaveRoom() {
		if (!this.currentRoom) return;

		// End game if playing
		if (this.gameState.isPlaying) {
			this.endGame();
		}

		this.disconnectGameSocket();

		try {
			const response = await fetch(API.ROOMS.LEAVE(this.currentRoom.id), {
				method: 'POST',
				headers: this.getHeaders()
			});

			if (!response.ok) {
				const data = await response.json();
				this.showMessage(data.error || 'Erreur', 'error');
				return;
			}

			eventBus.emit(Events.ROOM_LEFT, this.currentRoom);
			this.exitLobby();
		} catch (error) {
			console.error('Leave room error:', error);
			this.showMessage('Erreur de connexion', 'error');
		}
	}

	exitLobby() {
		this.currentRoom = null;
		this.lobbyTab.style.display = 'none';
		this.playerList.innerHTML = '';
		this.lobbyTitle.textContent = '';
		this.resetGameUI();
		this.switchTab('browse');
	}

	showMessage(text, type = 'info') {
		// Clear any existing timeout
		if (this.messageTimeout) {
			clearTimeout(this.messageTimeout);
		}

		this.message.textContent = text;
		this.message.className = CSS.MESSAGE;

		if (type === 'success') {
			this.message.classList.add(CSS.MESSAGE_SUCCESS);
		} else if (type === 'error') {
			this.message.classList.add(CSS.MESSAGE_ERROR);
		} else {
			this.message.classList.add(CSS.MESSAGE_INFO);
		}

		// Auto-clear message after 5 seconds
		this.messageTimeout = setTimeout(() => {
			this.message.textContent = '';
			this.message.className = CSS.MESSAGE;
		}, 5000);
	}

	// ============================================
	// LOGIQUE DU JEU
	// ============================================

	getCurrentUsername() {
		const token = localStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
		if (!token) return null;
		try {
			const payload = JSON.parse(atob(token.split('.')[1]));
			return payload.username || payload.sub || 'Joueur';
		} catch {
			return 'Joueur';
		}
	}

	isCurrentUserDrawer() {
		return this.gameState.drawer === this.getCurrentUsername();
	}

	showGameUI() {
		this.gameContainer.style.display = 'flex';
		this.playerList.style.display = 'none';
		this.lobbyButtons.style.display = 'none';
		this.clearCanvas();
		this.guessHistory.innerHTML = '';

		// If spectating, show indicator and disable interactions
		if (this.isSpectating) {
			this.currentDrawerInfo.textContent = '👁️ MODE SPECTATEUR - Vous regardez la partie';
			this.currentDrawerInfo.style.backgroundColor = '#2196F3';
			this.currentDrawerInfo.style.color = 'white';
			this.currentDrawerInfo.style.padding = '8px';
			this.currentDrawerInfo.style.borderRadius = '4px';
			this.currentDrawerInfo.style.textAlign = 'center';
			
			// Change button text for spectators
			this.backToLobbyBtn.textContent = 'Arrêter de regarder';
			this.endRoundBtn.style.display = 'none'; // Hide end game button for spectators
		} else {
			this.backToLobbyBtn.textContent = 'Quitter la partie';
			this.endRoundBtn.style.display = 'inline-block';
		}
	}

	resetGameUI() {
		this.gameState.isPlaying = false;
		this.gameState.currentWord = '';
		this.gameState.wordLength = 0;
		this.gameState.revealedLetters = [];
		this.gameState.revealedWord = [];
		this.gameState.drawer = null;
		this.isSpectating = false;

		this.gameState.scores = {};
   		this.gameState.players = [];
   		this.gameState.currentPlayerIndex = 0;
    	this.gameState.guessedLetters = [];

    	// Clear scores display
    	if (this.scoresDisplay)
        	this.scoresDisplay.textContent = '';

		if (this.guessHistory)
			this.guessHistory.innerHTML = '';

		this.clearCanvas();

		this.gameContainer.style.display = 'none';
		this.playerList.style.display = 'flex';
		this.lobbyButtons.style.display = 'flex';

		this.wordInputContainer.style.display = 'none';
		this.guessContainer.style.display = 'none';
		this.drawTools.style.display = 'none';

		// Reset spectator styling
		this.currentDrawerInfo.style.backgroundColor = '';
		this.currentDrawerInfo.style.color = '';
		this.currentDrawerInfo.style.padding = '';
		this.currentDrawerInfo.style.borderRadius = '';
		this.currentDrawerInfo.style.textAlign = '';
		this.currentDrawerInfo.classList.remove('gameroom__drawer-info--winner');
	}

	async startGame() {
		console.log('startGame called');

		// Load player list
		await this.loadLobby();

		const playerElements = this.playerList.querySelectorAll('.gameroom__player-name');
		const players = Array.from(playerElements).map(el => el.textContent);

		console.log('Players found:', players);

		if (players.length < 2) {
			this.showMessage('Il faut au moins 2 joueurs pour commencer', 'error');
			return;
		}

		const drawer = players[0];

		console.log('Socket connected:', this.socket?.connected, 'Socket ready:', this.socketReady);

		// Send start game event via WebSocket
		if (this.socket?.connected) {
			console.log('Emitting game-start event');
			this.socket.emit('game-start', { drawer, players });
		} else {
			console.log('No socket, using local fallback');
			// Fallback local - start immediately
			this.gameState.isPlaying = true;
			this.gameState.players = players;
			this.gameState.drawer = drawer;
			this.gameState.currentPlayerIndex = 0;
			this.showGameUI();
			this.setupRound();
		}
	}

	setupRound() {
		this.gameState.currentWord = '';
		this.gameState.wordLength = 0;
		this.gameState.revealedLetters = [];
		this.gameState.revealedWord = [];
		this.gameState.guessedLetters = [];

		this.currentDrawerInfo.textContent = `C'est au tour de ${this.gameState.drawer} de dessiner`;
		this.currentDrawerInfo.classList.remove('gameroom__drawer-info--winner');
		this.wordDisplay.textContent = '';
		this.guessHistory.innerHTML = '';
		this.clearCanvas();

		// Spectators cannot interact
		if (this.isSpectating) {
			this.wordInputContainer.style.display = 'none';
			this.guessContainer.style.display = 'none';
			this.drawTools.style.display = 'none';
			this.currentDrawerInfo.textContent = '👁️ MODE SPECTATEUR - Vous regardez la partie';
			return;
		}

		if (this.isCurrentUserDrawer()) {
			// Drawer chooses a word
			this.wordInputContainer.style.display = 'flex';
			this.guessContainer.style.display = 'none';
			this.drawTools.style.display = 'none';
			this.currentDrawerInfo.textContent = 'Choisissez un mot a faire deviner';
		} else {
			// Others see the guess input (disabled while waiting for word)
			this.wordInputContainer.style.display = 'none';
			this.guessContainer.style.display = 'flex';
			this.drawTools.style.display = 'none';
			this.letterInput.disabled = true;
			this.guessBtn.disabled = true;
			this.letterInput.placeholder = 'En attente du mot...';
			this.currentDrawerInfo.textContent = `${this.gameState.drawer} choisit un mot...`;
		}
	}

	confirmWord() {
		const word = this.wordInput.value.trim().toLowerCase();
		if (!word || word.length < 2) {
			this.showMessage('Le mot doit faire au moins 2 lettres', 'error');
			return;
		}

		if (!/^[a-z]+$/.test(word)) {
			this.showMessage('Le mot ne doit contenir que des lettres', 'error');
			return;
		}

		this.gameState.currentWord = word;
		this.gameState.wordLength = word.length;
		this.gameState.revealedLetters = new Array(word.length).fill(false);
		this.gameState.revealedWord = new Array(word.length).fill('_');

		this.wordInput.value = '';
		this.wordInputContainer.style.display = 'none';
		this.drawTools.style.display = 'flex';

		// Send word to server via WebSocket
		if (this.socket?.connected) {
			this.socket.emit('game-set-word', { word });
		}

		this.updateWordDisplay();
		this.currentDrawerInfo.textContent = `Dessinez pour faire deviner le mot (${word.length} lettres)`;
	}

	updateWordDisplay() {
		// If drawer, show from currentWord
		if (this.isCurrentUserDrawer() && this.gameState.currentWord) {
			let display = '';
			for (let i = 0; i < this.gameState.currentWord.length; i++) {
				if (this.gameState.revealedLetters && this.gameState.revealedLetters[i]) {
					display += this.gameState.currentWord[i] + ' ';
				} else {
					display += '_ ';
				}
			}
			this.wordDisplay.textContent = display.trim();
			return;
		}

		// For guessers, use revealedWord from server
		if (this.gameState.revealedWord && this.gameState.revealedWord.length > 0) {
			this.wordDisplay.textContent = this.gameState.revealedWord.join(' ');
			return;
		}

		// Fallback: show underscores based on wordLength
		if (this.gameState.wordLength > 0) {
			this.wordDisplay.textContent = '_ '.repeat(this.gameState.wordLength).trim();
		}
	}

	makeGuess() {
		const guess = this.letterInput.value.trim().toLowerCase();
		if (!guess) return;

		this.letterInput.value = '';

		// Send guess via WebSocket
		if (this.socket?.connected) {
			this.socket.emit('game-guess', { guess });
		} else {
			// Fallback local (for testing)
			this.processGuessLocally(guess);
		}
	}

	processGuessLocally(guess) {
		const username = this.getCurrentUsername();

		if (guess.length > 1) {
			const success = guess === this.gameState.currentWord;
			this.addGuessToHistory(guess, success, 'word', username);
			if (success) {
				this.gameState.revealedWord = this.gameState.currentWord.split('');
				this.wordFound(this.gameState.currentWord, username);
			}
			return;
		}

		if (this.gameState.guessedLetters.includes(guess)) {
			this.showMessage('Lettre deja proposee', 'info');
			return;
		}

		this.gameState.guessedLetters.push(guess);

		let found = false;
		for (let i = 0; i < this.gameState.currentWord.length; i++) {
			if (this.gameState.currentWord[i] === guess) {
				this.gameState.revealedLetters[i] = true;
				this.gameState.revealedWord[i] = guess;
				found = true;
			}
		}

		this.addGuessToHistory(guess, found, 'letter', username);
		this.updateWordDisplay();

		if (this.gameState.revealedLetters.every(r => r)) {
			this.wordFound(this.gameState.currentWord, username);
		}
	}

	addGuessToHistory(guess, success, type, username, points = 0) {
		const item = this.createElement('div', 'gameroom__guess-item');
		item.classList.add(success ? 'gameroom__guess-item--success' : 'gameroom__guess-item--fail');

		const typeText = type === 'letter' ? 'lettre' : 'mot';
		const pointsText = points !== 0 ? ` (${points > 0 ? '+' : ''}${points} pts)` : '';

		if (success) {
			item.textContent = `${username}: "${guess}" - Bon ${typeText}!${pointsText}`;
		} else {
			item.textContent = `${username}: "${guess}" - Mauvais ${typeText}${pointsText}`;
		}

		this.guessHistory.appendChild(item);
		this.guessHistory.scrollTop = this.guessHistory.scrollHeight;
	}

	updateScoresDisplay(scores) {
		if (!scores) return;
		this.gameState.scores = scores;

		// Update scores display in game UI
		if (this.scoresDisplay) {
			const sortedScores = Object.entries(scores)
				.sort((a, b) => b[1] - a[1])
				.map(([name, score]) => `${name}: ${score}`)
				.join(' | ');
			this.scoresDisplay.textContent = sortedScores;
		}

		// Update player list with scores if visible
		const playerItems = this.playerList.querySelectorAll('.gameroom__player');
		playerItems.forEach(item => {
			const nameEl = item.querySelector('.gameroom__player-name');
			const scoreEl = item.querySelector('.gameroom__player-score');
			if (nameEl && scoreEl) {
				const playerName = nameEl.textContent;
				const score = scores[playerName] || 0;
				scoreEl.textContent = `${score} pts`;
			}
		});
	}

	wordFound(word, winner, drawerBonus = 0) {
		let message = `${winner} a trouve le mot: ${word}!`;
		if (drawerBonus > 0 && this.gameState.drawer) {
			message += ` (${this.gameState.drawer} +${drawerBonus} pts)`;
		}
		this.currentDrawerInfo.textContent = message;
		this.currentDrawerInfo.classList.add('gameroom__drawer-info--winner');

		this.guessContainer.style.display = 'none';
		this.drawTools.style.display = 'none';

		// Reveal full word
		this.wordDisplay.textContent = word.split('').join(' ');

		// Auto next round after delay
		this.gameState.counterRound++;
		setTimeout(() => {
			if (this.gameState.counterRound >= (this.gameState.players.length * 4))
				this.endGame();
			if (this.gameState.isPlaying) {
				this.nextRound();
			}
		}, 3000);
	}

	nextRound() {
		// Move to next player
		this.gameState.counter++;
		if (this.gameState.counter >= this.gameState.players.length) {
			this.gameState.counter = 0;
		}
		const nextDrawer = this.gameState.players[this.gameState.counter];

		if (this.socket?.connected) {
			this.socket.emit('game-next-round', { drawer: nextDrawer });
		} else {
			this.gameState.drawer = nextDrawer;
			this.setupRound();
		}
	}

	backToLobby() {
		if (this.socket?.connected) {
			this.socket.emit('leave-room-during-game');
		}

		// Return to lobby without ending game for others
		this.resetGameUI();
		this.exitLobby();
		this.showMessage('Vous avez quitté la partie', 'info');
	}

	endGame() {
		if (this.socket?.connected) {
			this.socket.emit('game-end');
		}
		this.resetGameUI();
		this.showMessage('Jeu termine', 'info');
	}
}
