<script>
	import { onMount, onDestroy } from 'svelte';
	import { get } from 'svelte/store';
	import {
		filteredMessages,
		connectionStatus,
		chatUserInfo,
		participants,
		messageVisibilityFilter,
		hiddenUsers,
		loadVisibilitySettings,
		selectedRealms,
		availableRealms,
		toggleRealmFilter,
		resetToGlobal,
		fetchRealmStats
	} from '$lib/chat/chatStore';
	import { chatWebSocket } from '$lib/chat/chatWebSocket';
	import { chatLayout } from '$lib/stores/chatLayout';
	import { auth, isAuthenticated } from '$lib/stores/auth';
	import {
		ttsEnabled,
		ttsSettings,
		ttsUserFilter,
		availableVoices,
		initVoices,
		loadSettings as loadTtsSettings,
		setVoice
	} from '$lib/chat/ttsStore';

	import ChatMessage from './ChatMessage.svelte';
	import ChatInput from './ChatInput.svelte';
	import ProfilePreview from './ProfilePreview.svelte';

	export let realmId;
	export let userColor = '#FFFFFF';
	export let chatEnabled = true;
	export let chatGuestsAllowed = true;
	export let hideHeader = false;
	export let hideTheaterMode = false;

	let messagesContainer;
	let autoScroll = true;
	let initialScrollDone = false; // Prevent handleScroll from disabling autoScroll before initial scroll
	let showMenu = false;  // Combined settings + participants menu
	let configCollapsed = false;  // Track if config section is collapsed
	let usersCollapsed = false;   // Track if users section is collapsed
	let realmsCollapsed = false;  // Track if realms section is collapsed
	let participantModMenuId = null;  // Track which participant's mod menu is open
	let modMenuPosition = { x: 0, y: 0 };  // Position for fixed mod menu
	let showRenameModal = false;
	let newGuestName = '';
	let hasNewMessage = false;
	let fadeTimeout;
	let activeProfilePreview = null;
	let chatInputRef;
	let honkAudio = null;
	let honkSoundUrl = null;
	let mentionedMessageIds = new Set(); // Track which messages have already played honk
	let wasAuthenticated = false; // Track previous auth state for reconnect detection

	$: isConnected = $connectionStatus === 'connected';

	// Auto-load participants when connected
	$: if (isConnected) {
		chatWebSocket.getParticipants();
	}

	// Reconnect WebSocket when user logs in or registers while already connected as guest
	$: {
		const nowAuthenticated = $isAuthenticated;
		if (nowAuthenticated && !wasAuthenticated && isConnected) {
			console.log('[ChatPanel] Auth state changed to authenticated, reconnecting...');
			chatWebSocket.manualReconnect();
		}
		wasAuthenticated = nowAuthenticated;
	}

	function toggleMenu() {
		showMenu = !showMenu;
		if (showMenu) {
			chatWebSocket.getParticipants();
			fetchRealmStats(); // Fetch realm stats for the REALMS section
		}
	}

	function toggleParticipantModMenu(participantId, event) {
		event.stopPropagation();
		if (participantModMenuId === participantId) {
			participantModMenuId = null;
		} else {
			const rect = event.target.getBoundingClientRect();
			modMenuPosition = { x: rect.right, y: rect.bottom + 2 };
			participantModMenuId = participantId;
		}
	}

	async function handleParticipantModAction(participant, action) {
		switch (action) {
			case 'kick':
				chatWebSocket.kickUser(participant.userId, 60, 'Kicked by moderator');
				break;
			case 'mute':
				chatWebSocket.muteUser(participant.userId, 0, 'Muted by moderator'); // 0 = permanent
				break;
			case 'ban':
				chatWebSocket.banUser(participant.userId, 'Banned by moderator');
				break;
			case 'promote':
				await promoteToModerator(participant.userId);
				break;
			case 'demote':
				await demoteFromModerator(participant.userId);
				break;
		}
		participantModMenuId = null;
	}

	async function promoteToModerator(userId) {
		if (!userId) return;
		try {
			const response = await fetch(`/api/admin/users/${userId}/promote-moderator`, {
				method: 'POST',
				credentials: 'include'
			});
			if (response.ok) {
				chatWebSocket.getParticipants(); // Refresh participants list
			}
		} catch (e) {
			console.error('Failed to promote user:', e);
		}
	}

	async function demoteFromModerator(userId) {
		if (!userId) return;
		try {
			const response = await fetch(`/api/admin/users/${userId}/demote-moderator`, {
				method: 'POST',
				credentials: 'include'
			});
			if (response.ok) {
				chatWebSocket.getParticipants(); // Refresh participants list
			}
		} catch (e) {
			console.error('Failed to demote user:', e);
		}
	}

	// Check if current user has mod powers
	$: hasModPowers = $chatUserInfo.isModerator || $chatUserInfo.isAdmin || $chatUserInfo.isStreamer;

	let chatLoadedAt = Date.now();

	async function loadActiveHonkSound() {
		try {
			const response = await fetch('/api/honk/active');
			if (response.ok) {
				const data = await response.json();
				if (data.honk && data.honk.filePath) {
					honkSoundUrl = data.honk.filePath;
					honkAudio = new Audio(honkSoundUrl);
					honkAudio.volume = 0.5;
					honkAudio.load();
				}
			}
		} catch (e) {
			// Silently fail - honk is non-essential
		}
	}

	function handleMentioned(event) {
		const { messageId, timestamp } = event.detail;

		// Only play honk once per message
		if (mentionedMessageIds.has(messageId)) return;
		mentionedMessageIds.add(messageId);

		// Only play honk for messages that arrived after chat loaded (not historical messages)
		const messageTime = timestamp ? new Date(timestamp).getTime() : Date.now();
		if (messageTime < chatLoadedAt - 5000) return;

		if (honkSoundUrl) {
			const audio = new Audio(honkSoundUrl);
			audio.volume = 0.5;
			audio.play().catch(() => {});
		}
	}

	onMount(() => {
		// Initialize TTS voices and load realm settings
		initVoices();
		loadTtsSettings(realmId);
		loadVisibilitySettings(realmId);

		// Load active honk sound for mentions
		loadActiveHonkSound();

		// Only connect if chat is enabled
		if (!chatEnabled) {
			return;
		}

		// Connect to chat - fetch fresh token if authenticated (uses httpOnly cookies)
		(async () => {
			let token = null;
			try {
				const response = await fetch('/api/auth/refresh', {
					method: 'POST',
					credentials: 'include'
				});
				if (response.ok) {
					const data = await response.json();
					if (data.token) {
						token = data.token;
					}
				}
			} catch (e) {
				// Not authenticated or refresh failed - connect as guest
			}
			console.log('Chat connecting with realmId:', realmId, token ? '(authenticated)' : '(guest)');
			chatWebSocket.connect(realmId, token);
		})();

		// Function to scroll to newest messages (bottom for UP flow, top for DOWN flow)
		const scrollToBottom = () => {
			if (autoScroll && messagesContainer) {
				requestAnimationFrame(() => {
					const messagesFromTop = get(chatLayout).messagesFromTop;
					if (messagesFromTop) {
						// column-reverse: newest at top, scroll to top
						messagesContainer.scrollTop = 0;
					} else {
						// normal: newest at bottom, scroll to bottom
						messagesContainer.scrollTop = messagesContainer.scrollHeight;
					}
					initialScrollDone = true;
				});
			}
		};

		// Scroll to bottom when new messages arrive
		const unsubscribe = filteredMessages.subscribe((msgs) => {
			scrollToBottom();
			// Trigger new message indicator for theater mode
			if ($chatLayout.theaterMode && msgs.length > 0) {
				hasNewMessage = true;
				clearTimeout(fadeTimeout);
				fadeTimeout = setTimeout(() => {
					hasNewMessage = false;
				}, 5000);
			}
		});

		// Watch for content size changes (e.g., when images load)
		// This ensures autoscroll works even when images finish loading after message is added
		let resizeObserver;
		if (messagesContainer) {
			resizeObserver = new ResizeObserver(() => {
				scrollToBottom();
			});
			resizeObserver.observe(messagesContainer);
		}

		return () => {
			unsubscribe();
			if (resizeObserver) {
				resizeObserver.disconnect();
			}
		};
	});

	onDestroy(() => {
		// Keep connection alive for terminal usage
		// chatWebSocket.disconnect();
		if (fadeTimeout) clearTimeout(fadeTimeout);
	});

	function handleSendMessage(event) {
		let { message, selfDestructSeconds } = event.detail;

		// Handle /graffiti command
		if (message.trim().toLowerCase() === '/graffiti') {
			const graffitiUrl = $auth.user?.graffitiUrl;
			if (graffitiUrl) {
				message = `[graffiti]${graffitiUrl}[/graffiti]`;
			} else {
				alert('You don\'t have a graffiti yet. Create one in Settings > Appearance.');
				return;
			}
		}

		chatWebSocket.sendMessage(message, userColor, selfDestructSeconds || 0);
	}

	function handleScroll() {
		// Ignore scroll events before initial scroll is done (prevents browser's initial position from disabling autoScroll)
		if (!initialScrollDone) return;

		const { scrollTop, scrollHeight, clientHeight } = messagesContainer;
		if ($chatLayout.messagesFromTop) {
			// column-reverse: user at "newest" means scrollTop near 0
			autoScroll = scrollTop <= 50;
		} else {
			// normal: user at bottom means scrollTop + clientHeight near scrollHeight
			autoScroll = scrollTop + clientHeight >= scrollHeight - 50;
		}
	}

	function handleDeleteMessage(messageId) {
		chatWebSocket.deleteMessage(messageId);
	}

	function handleModAction(event) {
		const { action, userId, duration, reason } = event.detail;

		switch (action) {
			case 'ban':
				chatWebSocket.banUser(userId, reason);
				break;
			case 'mute':
				chatWebSocket.muteUser(userId, duration || 0, reason); // 0 = permanent by default
				break;
		}
	}

	function handleRename() {
		if (!newGuestName || newGuestName.trim().length === 0) {
			alert('Please enter a name');
			return;
		}

		// Send rename message to server
		// Note: State updates (localStorage + store) happen in rename_success handler
		// to avoid updating UI before server confirms the rename
		if (chatWebSocket.sendRename(newGuestName.trim())) {
			showRenameModal = false;
			newGuestName = '';
		} else {
			alert('Failed to send rename request');
		}
	}

	function handleClickOutside(event) {
		// Close combined menu when clicking outside
		if (showMenu) {
			const menuContainer = event.target.closest('.menu-container');
			const combinedMenu = event.target.closest('.combined-menu');
			if (!menuContainer && !combinedMenu) {
				showMenu = false;
				participantModMenuId = null;
			}
		}
		// Close participant mod menu when clicking outside
		if (participantModMenuId !== null) {
			const modContainer = event.target.closest('.participant-mod-container');
			if (!modContainer) {
				participantModMenuId = null;
			}
		}
	}

	function handleCopySticker(event) {
		const { stickerName } = event.detail;
		if (chatInputRef) {
			chatInputRef.insertText(stickerName);
		}
	}

	function handleMention(event) {
		const { username } = event.detail;
		if (chatInputRef) {
			chatInputRef.insertText(`@${username} `);
		}
	}

	function handleShowProfile(event) {
		const { username, userId, isGuest, messageId, position } = event.detail;
		activeProfilePreview = {
			username,
			userId,
			isGuest,
			messageId,
			position
		};
	}

	function handleProfileClose() {
		activeProfilePreview = null;
	}

	function popoutChat() {
		const realmParam = realmId ? `?realm=${realmId}` : '';
		const popoutUrl = `/chat/popout${realmParam}`;
		window.open(
			popoutUrl,
			'ChatPopout',
			'width=400,height=700,menubar=no,toolbar=no,location=no,status=no'
		);
	}

	// Check if currently showing global (all realms)
	$: isGlobalMode = $selectedRealms.size === 0;
</script>

<svelte:window on:click={handleClickOutside} />

<div
	class="chat-panel"
	class:inverted={$chatLayout.inverted}
	class:messages-from-top={$chatLayout.messagesFromTop}
	class:theater-mode={$chatLayout.theaterMode && !hideTheaterMode}
	class:has-new-message={hasNewMessage}
	on:mouseenter={() => { if ($chatLayout.theaterMode && !hideTheaterMode) hasNewMessage = true; }}
	on:mouseleave={() => { if ($chatLayout.theaterMode && !hideTheaterMode) { clearTimeout(fadeTimeout); fadeTimeout = setTimeout(() => hasNewMessage = false, 3000); } }}
>


	{#if showRenameModal}
		<div class="modal-overlay" on:click={() => showRenameModal = false}>
			<div class="modal-content small" on:click|stopPropagation>
				<div class="modal-header">
					<h3>Change Display Name</h3>
					<button class="close-btn" on:click={() => showRenameModal = false}>×</button>
				</div>
				<div class="rename-form">
					<p style="color: #999; font-size: 0.9rem; margin-bottom: 1rem;">
						Current name: <span style="color: {userColor}; font-weight: 600;">{$chatUserInfo.username}</span>
					</p>
					<form on:submit|preventDefault={handleRename}>
						<input
							type="text"
							bind:value={newGuestName}
							placeholder="Enter new name..."
							maxlength="30"
							pattern="[a-zA-Z0-9_-]+"
							title="Letters, numbers, underscores, and hyphens only"
							style="width: 100%; padding: 0.75rem; background: #2a2a2a; border: 1px solid #444; border-radius: 4px; color: #fff; font-size: 1rem; margin-bottom: 1rem;"
							required
						/>
						<div style="display: flex; gap: 0.5rem;">
							<button type="submit" class="btn-primary" style="flex: 1; padding: 0.75rem; background: #4a9eff; border: none; border-radius: 4px; color: #fff; font-weight: 600; cursor: pointer;">
								Change Name
							</button>
							<button type="button" class="btn-secondary" on:click={() => showRenameModal = false} style="flex: 1; padding: 0.75rem; background: #444; border: none; border-radius: 4px; color: #fff; font-weight: 600; cursor: pointer;">
								Cancel
							</button>
						</div>
					</form>
				</div>
			</div>
		</div>
	{/if}

	{#if !hideHeader}
	<div class="chat-header" class:menu-open={showMenu}>
		<h3 class="realm-title">{realmId || 'Global'}</h3>
		<div class="header-actions">
			{#if chatEnabled && isConnected && $chatUserInfo.isGuest}
				<button class="header-btn" on:click={() => showRenameModal = true} title="Change Display Name">
					<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor">
						<path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
					</svg>
				</button>
			{/if}

			<!-- Popout button -->
			<button class="header-btn" on:click={popoutChat} title="Pop out chat">
				<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor">
					<path d="M6.5 1A.5.5 0 0 1 7 .5h7a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0V1.5H7a.5.5 0 0 1-.5-.5z"/>
					<path d="M13.5 1l-6 6H4a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1h5a1 1 0 0 0 1-1V9.5l6-6z"/>
				</svg>
			</button>

			<!-- Combined Menu button (settings + participants) -->
			{#if chatEnabled}
				<div class="menu-container">
					<button class="header-btn menu-btn" on:click={toggleMenu} title="Menu">
						<span class="status-dot" class:connected={isConnected} class:disconnected={!isConnected}></span>
						<span class="btn-count">{$participants.length}</span>
					</button>
				</div>
			{/if}

		</div>
	</div>

	<!-- Combined menu - positioned relative to chat-panel, outside chat-header -->
	{#if showMenu}
		<div class="combined-menu" on:click|stopPropagation>
			<!-- Settings Section (Collapsible) -->
			<div class="menu-section">
				<button class="menu-section-header collapsible" on:click={() => configCollapsed = !configCollapsed}>
					<span class="collapse-arrow" class:collapsed={configCollapsed}>▼</span>
					-- CONFIG --
				</button>
				{#if !configCollapsed}
				<div class="config-columns">
					<!-- Left column: Layout options -->
					<div class="config-column">
						<button class="menu-option" on:click={() => chatLayout.togglePosition()}>
							<span class="option-marker">></span>
							<span class="option-label">position:</span>
							<span class="option-value">{$chatLayout.position.toUpperCase()}</span>
						</button>
						<button class="menu-option" on:click={() => chatLayout.toggleInverted()}>
							<span class="option-marker">></span>
							<span class="option-label">input:</span>
							<span class="option-value">{$chatLayout.inverted ? 'TOP' : 'BOTTOM'}</span>
						</button>
						<button class="menu-option" on:click={() => chatLayout.toggleMessagesFromTop()}>
							<span class="option-marker">></span>
							<span class="option-label">flow:</span>
							<span class="option-value">{$chatLayout.messagesFromTop ? 'DOWN' : 'UP'}</span>
						</button>
						{#if !hideTheaterMode}
							<button class="menu-option" on:click={() => chatLayout.toggleTheaterMode()}>
								<span class="option-marker">></span>
								<span class="option-label">theater:</span>
								<span class="option-value" class:active-on={$chatLayout.theaterMode}>{$chatLayout.theaterMode ? 'ON' : 'OFF'}</span>
							</button>
						{/if}
						<div class="menu-option-row">
							<span class="option-marker">></span>
							<span class="option-label">show:</span>
							<select class="inline-select" value={$messageVisibilityFilter} on:change={(e) => messageVisibilityFilter.set(e.target.value)}>
								<option value="all">ALL</option>
								<option value="registered">REG</option>
								<option value="guests">GUEST</option>
							</select>
						</div>
					</div>
					<!-- Right column: TTS options -->
					<div class="config-column tts-column">
						<button class="menu-option" on:click={() => ttsEnabled.update(v => !v)}>
							<span class="option-marker">></span>
							<span class="option-label">tts:</span>
							<span class="option-value" class:active-on={$ttsEnabled}>{$ttsEnabled ? 'ON' : 'OFF'}</span>
						</button>
						<div class="menu-option-row">
							<span class="option-marker"> </span>
							<span class="option-label">voice:</span>
							<select class="inline-select" value={$ttsSettings.voiceName} on:change={(e) => setVoice(e.target.value)}>
								<option value="">default</option>
								{#each $availableVoices as voice}
									<option value={voice.name}>{voice.name}</option>
								{/each}
							</select>
						</div>
						<div class="menu-option-row">
							<span class="option-marker"> </span>
							<span class="option-label">speed:</span>
							<input type="range" class="inline-range" min="0.1" max="4" step="0.1" value={$ttsSettings.rate} on:input={(e) => ttsSettings.update(s => ({ ...s, rate: parseFloat(e.target.value) }))} />
							<span class="range-value">{$ttsSettings.rate.toFixed(1)}</span>
						</div>
						<div class="menu-option-row">
							<span class="option-marker"> </span>
							<span class="option-label">pitch:</span>
							<input type="range" class="inline-range" min="0" max="2" step="0.1" value={$ttsSettings.pitch} on:input={(e) => ttsSettings.update(s => ({ ...s, pitch: parseFloat(e.target.value) }))} />
							<span class="range-value">{$ttsSettings.pitch.toFixed(1)}</span>
						</div>
						<div class="menu-option-row">
							<span class="option-marker"> </span>
							<span class="option-label">volume:</span>
							<input type="range" class="inline-range" min="0" max="1" step="0.1" value={$ttsSettings.volume} on:input={(e) => ttsSettings.update(s => ({ ...s, volume: parseFloat(e.target.value) }))} />
							<span class="range-value">{$ttsSettings.volume.toFixed(1)}</span>
						</div>
					</div>
				</div>
				{/if}
			</div>
			<!-- Users Section (Collapsible) -->
			<div class="menu-section">
				<button class="menu-section-header collapsible" on:click={() => usersCollapsed = !usersCollapsed}>
					<span class="collapse-arrow" class:collapsed={usersCollapsed}>▼</span>
					-- USERS ({$participants.length}) --
				</button>
				{#if !usersCollapsed}
				<div class="users-list">
					{#each $participants as participant (participant.userId)}
						<div class="user-row">
							<span class="user-prefix">{participant.isStreamer ? '*' : participant.isModerator ? '+' : ' '}</span>
							<button
								class="user-name-btn"
								class:guest={participant.isGuest}
								style={participant.userColor && !participant.isGuest ? `color: ${participant.userColor}` : ''}
								on:click={(e) => {
									// Toggle: close if same user, open if different
									if (activeProfilePreview && activeProfilePreview.userId === participant.userId) {
										activeProfilePreview = null;
									} else {
										const rect = e.target.getBoundingClientRect();
										activeProfilePreview = {
											username: participant.username,
											userId: participant.userId,
											isGuest: participant.isGuest,
											position: { x: rect.left, y: rect.bottom + 4 }
										};
									}
								}}
								on:auxclick={(e) => {
									// Middle-click opens profile in new tab
									if (e.button === 1 && !participant.isGuest) {
										e.preventDefault();
										window.open(`/profile/${participant.username}`, '_blank');
									}
								}}
							>{participant.username}</button>
							{#if hasModPowers && participant.userId !== $chatUserInfo.userId && !participant.isStreamer && ($chatUserInfo.isAdmin || !participant.isModerator)}
								<div class="participant-mod-container">
									<button class="user-mod-btn" on:click={(e) => toggleParticipantModMenu(participant.userId, e)}>...</button>
									{#if participantModMenuId === participant.userId}
										<div class="user-mod-menu" style="left: {modMenuPosition.x}px; top: {modMenuPosition.y}px; transform: translateX(-100%);" on:click|stopPropagation>
											<button on:click={() => handleParticipantModAction(participant, 'kick')}>kick</button>
											<button on:click={() => handleParticipantModAction(participant, 'mute')}>mute</button>
											<button class="danger" on:click={() => handleParticipantModAction(participant, 'ban')}>ban</button>
											{#if $chatUserInfo.isAdmin && !participant.isGuest}
												{#if participant.isModerator}
													<button class="warn" on:click={() => handleParticipantModAction(participant, 'demote')}>demote</button>
												{:else}
													<button class="success" on:click={() => handleParticipantModAction(participant, 'promote')}>promote</button>
												{/if}
											{/if}
										</div>
									{/if}
								</div>
							{/if}
						</div>
					{/each}
					{#if $participants.length === 0}
						<div class="empty-users">no users online</div>
					{/if}
				</div>
				{/if}
			</div>
			<!-- Realms Section (Collapsible) -->
			<div class="menu-section">
				<button class="menu-section-header collapsible" on:click={() => realmsCollapsed = !realmsCollapsed}>
					<span class="collapse-arrow" class:collapsed={realmsCollapsed}>▼</span>
					-- REALMS --
				</button>
				{#if !realmsCollapsed}
				<div class="realms-list">
					<div class="realm-row" class:active={isGlobalMode}>
						<button class="realm-name-btn" on:click={() => resetToGlobal()}>
							<span class="realm-marker">{isGlobalMode ? '>' : ' '}</span>
							GLOBAL
						</button>
					</div>
					{#each $availableRealms as realm (realm.realmId)}
						<div class="realm-row" class:active={$selectedRealms.has(realm.realmId)}>
							<button class="realm-name-btn" on:click={() => toggleRealmFilter(realm.realmId)}>
								<span class="realm-marker">{$selectedRealms.has(realm.realmId) ? '>' : ' '}</span>
								{realm.realmId}
							</button>
							<span class="realm-count">{realm.participantCount}</span>
						</div>
					{/each}
					{#if $availableRealms.length === 0}
						<div class="empty-realms">no realms</div>
					{/if}
				</div>
				{/if}
			</div>
		</div>
	{/if}
	{/if}

	{#if !chatEnabled}
		<div class="chat-disabled-message">
			<div class="disabled-icon">💬</div>
			<p><strong>Chat Disabled</strong></p>
			<p class="disabled-text">The streamer has disabled chat for this realm.</p>
		</div>
	{:else if !chatGuestsAllowed && $chatUserInfo.isGuest}
		<div class="chat-disabled-message">
			<div class="disabled-icon">🔒</div>
			<p><strong>Guests Not Allowed</strong></p>
			<p class="disabled-text">This chat requires authentication. Please log in to participate.</p>
			<a href="/login" class="btn" style="margin-top: 1rem; padding: 0.75rem 1.5rem; background: var(--primary); color: white; text-decoration: none; border-radius: 4px; display: inline-block;">
				Login
			</a>
		</div>
	{:else}
		<div class="messages-container" bind:this={messagesContainer} on:scroll={handleScroll}>
			{#each $filteredMessages as message (message.messageId)}
				<ChatMessage
					{message}
					showHeader={message.showHeader ?? false}
					currentUserId={$chatUserInfo.userId}
					currentUsername={$chatUserInfo.username}
					currentRealmId={realmId}
					isModerator={$chatUserInfo.isModerator}
					isAdmin={$chatUserInfo.isAdmin}
					on:delete={() => handleDeleteMessage(message.messageId)}
					on:modAction={handleModAction}
					on:showProfile={handleShowProfile}
					on:copySticker={handleCopySticker}
					on:mentioned={handleMentioned}
					on:mention={handleMention}
				/>
			{/each}

			{#if $filteredMessages.length === 0}
				<div class="empty-state">
					<p>No messages yet. Be the first to chat!</p>
				</div>
			{/if}
		</div>

		<ChatInput
			bind:this={chatInputRef}
			disabled={!isConnected}
			username={$chatUserInfo.username}
			isGuest={$chatUserInfo.isGuest}
			on:send={handleSendMessage}
		/>
	{/if}

	{#if activeProfilePreview}
		<ProfilePreview
			username={activeProfilePreview.username}
			userId={activeProfilePreview.userId}
			isGuest={activeProfilePreview.isGuest}
			position={activeProfilePreview.position}
			on:close={handleProfileClose}
		/>
	{/if}
</div>

<style>
	.chat-panel {
		display: flex;
		flex-direction: column;
		height: 100%;
		max-height: 100%;
		min-height: 0;
		background: #1a1a1a;
		position: relative;
		overflow: hidden; /* Prevent panel itself from scrolling */
	}

	.chat-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 0.5rem;
		border-bottom: 1px solid #333;
		background: #000;
		flex-shrink: 0;
		position: relative;
	}

	.chat-header h3 {
		margin: 0;
		font-size: 1rem;
		color: #fff;
	}

	.realm-title {
		flex: 1;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.header-actions {
		display: flex;
		align-items: center;
		gap: 0.375rem;
	}

	/* Unified slim header button style */
	.header-btn {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 0.25rem;
		height: 26px;
		min-width: 26px;
		padding: 0 0.375rem;
		background: rgba(255, 255, 255, 0.08);
		border: 1px solid rgba(255, 255, 255, 0.15);
		border-radius: 4px;
		color: #aaa;
		cursor: pointer;
		font-size: 0.75rem;
		transition: all 0.15s;
	}

	.header-btn:hover {
		background: rgba(255, 255, 255, 0.12);
		border-color: rgba(255, 255, 255, 0.25);
		color: #fff;
	}

	.header-btn .status-dot {
		width: 6px;
		height: 6px;
		border-radius: 50%;
		background: #666;
		flex-shrink: 0;
	}

	.header-btn .status-dot.connected {
		background: #0f0;
	}

	.header-btn .status-dot.disconnected {
		background: #f44336;
	}

	.btn-count {
		font-weight: 500;
	}

	.messages-container {
		flex: 1 1 0; /* Grow, shrink, base 0 */
		background: #000;
		overflow-y: auto;
		overflow-x: hidden;
		padding: 0.25rem;
		display: flex;
		flex-direction: column;
		gap: 0.125rem;
		min-height: 0; /* Allow flex shrinking */
		max-height: 100%; /* Don't exceed container */
		width: 100%; /* Ensure full width */
	}

	.empty-state {
		flex: 1;
		display: flex;
		align-items: center;
		justify-content: center;
		color: #666;
		font-style: italic;
	}

	.chat-disabled-message {
		flex: 1;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		padding: 2rem;
		text-align: center;
		color: #999;
	}

	.disabled-icon {
		font-size: 3rem;
		margin-bottom: 1rem;
		opacity: 0.5;
	}

	.chat-disabled-message p {
		margin: 0.5rem 0;
	}

	.chat-disabled-message strong {
		color: #fff;
		font-size: 1.1rem;
	}

	.disabled-text {
		font-size: 0.9rem;
		color: #666;
	}

	/* Combined Menu (Terminal Style) */
	.menu-container {
		position: static;
	}

	.combined-menu {
		position: absolute;
		left: 0;
		right: 0;
		top: 38px; /* Height of header */
		background: #0a0a0a;
		border-bottom: 1px solid #333;
		max-height: 50%;
		overflow-y: auto;
		overflow-x: hidden;
		z-index: 200;
		font-family: var(--font-mono);
		font-size: 0.75rem;
	}

	.menu-section {
		border-bottom: 1px solid #222;
	}

	.menu-section:last-child {
		border-bottom: none;
	}

	.menu-section-header {
		display: block;
		width: 100%;
		padding: 0.5rem 0.75rem;
		color: #888;
		font-size: 0.7rem;
		letter-spacing: 1px;
		background: #0d0d0d;
		text-align: center;
		border: none;
		font-family: inherit;
	}

	.menu-section-header.collapsible {
		cursor: pointer;
		display: flex;
		align-items: center;
		justify-content: center;
		position: relative;
	}

	.menu-section-header.collapsible:hover {
		color: #aaa;
	}

	.collapse-arrow {
		position: absolute;
		left: 0.75rem;
		font-size: 0.55rem;
		transition: transform 0.15s ease;
		opacity: 0.6;
	}

	.collapse-arrow.collapsed {
		transform: rotate(-90deg);
	}

	.config-columns {
		display: flex;
		gap: 1px;
		background: #222;
		min-width: 0;
	}

	.config-column {
		flex: 1;
		min-width: 0;
		background: #0a0a0a;
		display: flex;
		flex-direction: column;
	}

	.config-column.tts-column {
		border-left: 1px solid #222;
	}

	.menu-option {
		display: flex;
		align-items: center;
		width: 100%;
		padding: 0.5rem 0.75rem;
		background: none;
		border: none;
		color: #aaa;
		font-family: inherit;
		font-size: inherit;
		cursor: pointer;
		text-align: left;
		transition: background 0.1s;
		min-width: 0;
		overflow: hidden;
	}

	.menu-option:hover {
		background: #1a1a1a;
		color: #fff;
	}

	.menu-option.active {
		color: #a855f7;
	}

	.menu-option-row {
		display: flex;
		align-items: center;
		padding: 0.5rem 0.75rem;
		color: #aaa;
		min-width: 0;
		overflow: hidden;
	}

	.option-marker {
		display: none;
	}

	.option-label {
		color: #888;
		margin-right: 0.5rem;
	}

	.option-value {
		color: #a855f7;
		margin-left: auto;
	}

	.option-value.active-on {
		color: #f00;
	}

	.option-count {
		color: #666;
		margin-left: auto;
		font-size: 0.65rem;
	}

	.inline-select {
		background: #111;
		border: 1px solid #333;
		color: #a855f7;
		font-family: inherit;
		font-size: inherit;
		padding: 0.125rem 0.25rem;
		cursor: pointer;
		margin-left: auto;
		max-width: 164px;
		min-width: 0;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.inline-select:hover {
		border-color: #555;
	}

	.inline-range {
		width: 60px;
		height: 4px;
		background: #333;
		border: none;
		margin-left: auto;
		cursor: pointer;
		-webkit-appearance: none;
	}

	.inline-range::-webkit-slider-thumb {
		-webkit-appearance: none;
		width: 8px;
		height: 8px;
		background: #0f0;
		cursor: pointer;
	}

	.range-value {
		width: 24px;
		text-align: right;
		color: #0f0;
		margin-left: 0.5rem;
	}

	/* Users Grid (3 columns) */
	.users-list {
		display: grid;
		grid-template-columns: repeat(3, 1fr);
		gap: 1px;
		background: #222;
		max-height: none;
		overflow-y: auto;
	}

	.user-row {
		display: flex;
		align-items: center;
		padding: 0.35rem 0.5rem;
		gap: 0.25rem;
		background: #0a0a0a;
		min-width: 0; /* Allow text truncation */
	}

	.user-row:hover {
		background: #1a1a1a;
	}

	.user-prefix {
		width: 0.75rem;
		color: #ff0;
		flex-shrink: 0;
		text-align: center;
		font-size: 0.7rem;
	}

	.user-name-btn {
		background: none;
		border: none;
		color: #ccc;
		font-family: inherit;
		font-size: inherit;
		padding: 0;
		cursor: pointer;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
		flex: 1;
		text-align: left;
		min-width: 0;
	}

	.user-name-btn:hover {
		color: #fff;
		text-decoration: underline;
	}

	.user-name-btn.guest {
		color: #666;
		font-style: italic;
	}

	.user-name-btn.guest:hover {
		color: #888;
	}

	.user-mod-btn {
		background: #222;
		border: 1px solid #333;
		color: #888;
		font-family: inherit;
		font-size: 0.6rem;
		cursor: pointer;
		padding: 0.1rem 0.25rem;
		flex-shrink: 0;
		line-height: 1;
	}

	.user-mod-btn:hover {
		background: #333;
		color: #fff;
		border-color: #444;
	}

	.user-mod-menu {
		position: fixed;
		background: #111;
		border: 1px solid #444;
		z-index: 1000;
		display: flex;
		flex-direction: column;
		min-width: 80px;
		box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
	}

	.user-mod-menu button {
		background: none;
		border: none;
		color: #aaa;
		font-family: inherit;
		font-size: 0.7rem;
		padding: 0.5rem 0.75rem;
		cursor: pointer;
		text-align: left;
	}

	.user-mod-menu button:hover {
		background: #1a1a1a;
		color: #fff;
	}

	.user-mod-menu button.danger {
		color: #f44;
	}

	.user-mod-menu button.danger:hover {
		background: #311;
	}

	.user-mod-menu button.warn {
		color: #fa0;
	}

	.user-mod-menu button.success {
		color: #0f0;
	}

	.empty-users {
		grid-column: 1 / -1; /* Span all columns */
		padding: 0.75rem;
		color: #555;
		text-align: center;
		font-style: italic;
		background: #0a0a0a;
	}

	/* Realms Grid (3 columns like users) */
	.realms-list {
		display: grid;
		grid-template-columns: repeat(3, 1fr);
		gap: 1px;
		background: #222;
	}

	.realm-row {
		display: flex;
		align-items: center;
		padding: 0.35rem 0.5rem;
		gap: 0.25rem;
		background: #0a0a0a;
		min-width: 0;
	}

	.realm-row:hover {
		background: #1a1a1a;
	}

	.realm-row.active {
		background: #1a1a1a;
	}

	.realm-name-btn {
		background: none;
		border: none;
		color: #888;
		font-family: inherit;
		font-size: inherit;
		padding: 0;
		cursor: pointer;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
		flex: 1;
		text-align: left;
		min-width: 0;
	}

	.realm-name-btn:hover {
		color: #ccc;
	}

	.realm-row.active .realm-name-btn {
		color: #0f0;
	}

	.realm-marker {
		color: #0f0;
		margin-right: 0.25rem;
	}

	.realm-count {
		color: #555;
		font-size: 0.65rem;
		flex-shrink: 0;
	}

	.empty-realms {
		grid-column: 1 / -1;
		padding: 0.75rem;
		color: #555;
		text-align: center;
		font-style: italic;
		background: #0a0a0a;
	}

	.participant-mod-container {
		position: relative;
	}

	.modal-overlay {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		background: rgba(0, 0, 0, 0.9);
		display: flex;
		align-items: center;
		justify-content: center;
		z-index: 100;
	}

	.modal-content {
		background: #1a1a1a;
		border: 1px solid #333;
		border-radius: 8px;
		width: 90%;
		max-width: 500px;
		max-height: 70vh;
		display: flex;
		flex-direction: column;
	}

	.modal-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 1rem;
		border-bottom: 1px solid #333;
	}

	.modal-header h3 {
		margin: 0;
		color: #fff;
		font-size: 1.1rem;
	}

	.close-btn {
		background: none;
		border: none;
		color: #999;
		font-size: 1.5rem;
		cursor: pointer;
		padding: 0;
		width: 32px;
		height: 32px;
		display: flex;
		align-items: center;
		justify-content: center;
		transition: color 0.2s;
	}

	.close-btn:hover {
		color: #fff;
	}


	.modal-content.small {
		max-width: 300px;
	}

	/* Inverted layout - input on top, header on bottom */
	.chat-panel.inverted .chat-header {
		order: 3;
		border-bottom: none;
		border-top: 1px solid #333;
	}

	.chat-panel.inverted .messages-container {
		order: 2;
	}

	.chat-panel.inverted :global(.chat-input) {
		order: 1;
	}

	/* Messages from top - newest messages at top */
	.chat-panel.messages-from-top .messages-container {
		flex-direction: column-reverse;
	}

	/* Theater mode styles */
	.chat-panel.theater-mode {
		background: rgba(0, 0, 0, 0.001); /* Nearly invisible but captures hover events */
		border: none;
		pointer-events: auto; /* Ensure panel receives pointer events */
	}

	.chat-panel.theater-mode .chat-header {
		background: rgba(0, 0, 0, 0.5);
		backdrop-filter: blur(8px);
		border-color: rgba(255, 255, 255, 0.1);
		opacity: 0;
		transition: opacity 0.3s;
		pointer-events: auto;
		position: relative;
		z-index: 100;
		overflow: visible;
	}

	.chat-panel.theater-mode:hover .chat-header,
	.chat-panel.theater-mode.has-new-message .chat-header,
	.chat-panel.theater-mode .chat-header.menu-open {
		opacity: 1;
	}

	.chat-panel.theater-mode .chat-header .header-btn {
		pointer-events: auto;
	}

	.chat-panel.theater-mode .menu-container {
		pointer-events: auto !important;
		position: relative;
		z-index: 300;
	}

	.chat-panel.theater-mode .combined-menu {
		pointer-events: auto !important;
		z-index: 400;
	}

	.chat-panel.theater-mode .combined-menu * {
		pointer-events: auto !important;
	}

	.chat-panel.theater-mode .messages-container {
		background: transparent;
		mask-image: linear-gradient(to top, black 60%, transparent 100%);
		-webkit-mask-image: linear-gradient(to top, black 60%, transparent 100%);
	}

	.chat-panel.theater-mode .messages-container :global(.chat-message) {
		background: rgba(0, 0, 0, 0.6);
		backdrop-filter: blur(4px);
		border-radius: 4px;
		padding: 0.5rem;
		opacity: 0;
		transition: opacity 0.5s;
	}

	.chat-panel.theater-mode:hover .messages-container :global(.chat-message),
	.chat-panel.theater-mode.has-new-message .messages-container :global(.chat-message) {
		opacity: 1;
	}

	.chat-panel.theater-mode :global(.chat-input) {
		background: rgba(0, 0, 0, 0.7);
		backdrop-filter: blur(8px);
		border-color: rgba(255, 255, 255, 0.1);
		opacity: 0;
		transition: opacity 0.3s;
	}

	.chat-panel.theater-mode:hover :global(.chat-input),
	.chat-panel.theater-mode.has-new-message :global(.chat-input) {
		opacity: 1;
	}

	/* Disabled/empty states in theater mode */
	.chat-panel.theater-mode .chat-disabled-message,
	.chat-panel.theater-mode .empty-state {
		background: rgba(0, 0, 0, 0.5);
		backdrop-filter: blur(4px);
		border-radius: 8px;
		padding: 1rem;
		opacity: 0.7;
	}

	/* Combined menu opens upward when chat is inverted (header at bottom) */
	.chat-panel.inverted .combined-menu {
		top: auto;
		bottom: 38px; /* Height of header */
		border-bottom: none;
		border-top: 1px solid #333;
	}
</style>
