<script lang="ts">
	import { onMount } from 'svelte';
	import { robotics } from 'lerobot-arena-client';
	import type { robotics as roboticsTypes } from 'lerobot-arena-client';

	// Get data from load function
	let { data } = $props();
	let workspaceId = data.workspaceId;
	let roomIdFromUrl = data.roomId;

	// State
	let consumer: robotics.RoboticsConsumer;
	let connected = $state<boolean>(false);
	let connecting = $state<boolean>(false);
	let roomId = $state<string>(roomIdFromUrl || '');
	let participantId = $state<string>('');
	let error = $state<string>('');

	// Current robot state
	let currentJoints = $state<Record<string, number>>({});
	let lastUpdate = $state<Date | null>(null);

	// Real-time monitoring
	let updateCount = $state<number>(0);
	let stateSyncCount = $state<number>(0);
	let errorCount = $state<number>(0);

	// History tracking
	let jointHistory = $state<
		Array<{ timestamp: string; joints: roboticsTypes.JointData[]; source?: string }>
	>([]);
	let stateHistory = $state<Array<{ timestamp: string; state: Record<string, number> }>>([]);
	let errorHistory = $state<Array<{ timestamp: string; message: string }>>([]);

	// Visualization data for joint trend (last 20 updates)
	let jointTrends = $state<Record<string, number[]>>({});

	// Debug info
	let debugInfo = $state<{
		connectionAttempts: number;
		messagesReceived: number;
		lastMessageType: string;
		wsConnected: boolean;
		currentRoom: string;
		workspaceId: string;
	}>({
		connectionAttempts: 0,
		messagesReceived: 0,
		lastMessageType: '',
		wsConnected: false,
		currentRoom: '',
		workspaceId: workspaceId
	});

	function updateUrlWithRoom(roomId: string) {
		const url = new URL(window.location.href);
		url.searchParams.set('room', roomId);
		window.history.replaceState({}, '', url.toString());
	}

	async function connectConsumer() {
		if (!roomId.trim() || !participantId.trim()) {
			error = 'Please enter both Room ID and Participant ID';
			return;
		}

		debugInfo.connectionAttempts++;

		try {
			connecting = true;
			error = '';

			consumer = new robotics.RoboticsConsumer('http://localhost:8000');

			// Set up event handlers
			consumer.onConnected(() => {
				connected = true;
				connecting = false;
				debugInfo.wsConnected = true;
				debugInfo.currentRoom = roomId;
				loadInitialState();
				updateUrlWithRoom(roomId);
			});

			consumer.onDisconnected(() => {
				connected = false;
				debugInfo.wsConnected = false;
			});

			consumer.onError((errorMsg) => {
				error = errorMsg;
				errorCount++;
				debugInfo.messagesReceived++;
				debugInfo.lastMessageType = 'ERROR';
				errorHistory = [
					{
						timestamp: new Date().toLocaleTimeString(),
						message: errorMsg
					},
					...errorHistory
				].slice(0, 10); // Keep last 10 errors only
			});

			// Joint update callback
			consumer.onJointUpdate((joints) => {
				updateCount++;
				lastUpdate = new Date();
				debugInfo.messagesReceived++;
				debugInfo.lastMessageType = 'JOINT_UPDATE';

				// Update current state
				joints.forEach((joint) => {
					currentJoints[joint.name] = joint.value;

					// Update trends
					if (!jointTrends[joint.name]) {
						jointTrends[joint.name] = [];
					}
					jointTrends[joint.name] = [...jointTrends[joint.name], joint.value].slice(-10); // Keep last 10 only
				});

				// Add to history
				jointHistory = [
					{
						timestamp: new Date().toLocaleTimeString(),
						joints,
						source: 'producer'
					},
					...jointHistory
				].slice(0, 20); // Keep last 20 updates only
			});

			// State sync callback
			consumer.onStateSync((state) => {
				stateSyncCount++;
				lastUpdate = new Date();
				debugInfo.messagesReceived++;
				debugInfo.lastMessageType = 'STATE_SYNC';

				// Update current state
				currentJoints = { ...state };

				// Update trends for all joints
				Object.entries(state).forEach(([name, value]) => {
					if (!jointTrends[name]) {
						jointTrends[name] = [];
					}
					jointTrends[name] = [...jointTrends[name], value].slice(-10); // Keep last 10 only
				});

				// Add to history
				stateHistory = [
					{
						timestamp: new Date().toLocaleTimeString(),
						state
					},
					...stateHistory
				].slice(0, 10); // Keep last 10 state syncs only
			});

			const success = await consumer.connect(workspaceId, roomId, participantId);
			if (!success) {
				error = 'Failed to connect. Room might not exist.';
				connecting = false;
			}
		} catch (err) {
			error = `Connection failed: ${err}`;
			connecting = false;
		}
	}

	async function loadInitialState() {
		if (!consumer || !connected) return;

		try {
			const state = await consumer.getStateSyncAsync();
			if (Object.keys(state).length > 0) {
				currentJoints = state;
				// Initialize trends
				Object.entries(state).forEach(([name, value]) => {
					jointTrends[name] = [value];
				});
			}
		} catch (err) {
			console.error('Failed to load initial state:', err);
		}
	}

	async function exitSession() {
		if (consumer && connected) {
			await consumer.disconnect();
		}
		connected = false;
		debugInfo.wsConnected = false;
		debugInfo.currentRoom = '';
	}

	function clearHistory() {
		jointHistory = [];
		stateHistory = [];
		errorHistory = [];
		updateCount = 0;
		stateSyncCount = 0;
		errorCount = 0;
		debugInfo.messagesReceived = 0;
	}

	// Update roomId when URL parameter changes
	$effect(() => {
		if (roomIdFromUrl) {
			roomId = roomIdFromUrl;
		}
	});

	// Update debugInfo when workspaceId changes
	$effect(() => {
		debugInfo.workspaceId = workspaceId;
	});

	onMount(() => {
		participantId = `consumer_${Date.now()}`;

		return () => {
			exitSession();
		};
	});
</script>

<svelte:head>
	<title>Robotics Consumer{roomId ? ` - Room ${roomId}` : ''} - Workspace {workspaceId} - LeRobot Arena</title>
</svelte:head>

<div class="mx-auto max-w-6xl space-y-6">
	<!-- Header -->
	<div class="flex items-center justify-between">
		<div>
			<h1 class="font-mono text-2xl font-bold text-gray-900">🤖 Robotics Consumer</h1>
			<p class="mt-1 font-mono text-sm text-gray-600">
				Workspace: <span class="font-bold text-blue-600">{workspaceId}</span>
				{#if roomId}
					| Room: <span class="font-bold text-blue-600">{roomId}</span>
				{:else}
					| Monitor robot arm state in real-time
				{/if}
			</p>
		</div>
		<div class="flex items-center space-x-4">
			<div class="flex items-center space-x-2">
				{#if connected}
					<div class="h-3 w-3 rounded-full bg-green-500"></div>
					<span class="font-mono text-sm font-medium text-green-700">Connected</span>
				{:else if connecting}
					<div class="h-3 w-3 animate-pulse rounded-full bg-yellow-500"></div>
					<span class="font-mono text-sm font-medium text-yellow-700">Connecting...</span>
				{:else}
					<div class="h-3 w-3 rounded-full bg-red-500"></div>
					<span class="font-mono text-sm font-medium text-red-700">Disconnected</span>
				{/if}
			</div>
			<a
				href="/{workspaceId}/robotics"
				class="rounded border bg-gray-100 px-3 py-2 font-mono text-sm hover:bg-gray-200"
			>
				← Back to Robotics
			</a>
		</div>
	</div>

	<!-- Debug Info -->
	<div class="rounded border bg-gray-900 p-4 font-mono text-sm text-green-400">
		<div class="mb-2 font-bold">ROBOTICS CONSUMER DEBUG - WORKSPACE {debugInfo.workspaceId}{roomId ? ` - ROOM ${roomId}` : ''}</div>
		<div class="grid grid-cols-3 gap-4 md:grid-cols-5">
			<div>Attempts: {debugInfo.connectionAttempts}</div>
			<div>Messages: {debugInfo.messagesReceived}</div>
			<div>Last: {debugInfo.lastMessageType || 'None'}</div>
			<div>WS: {debugInfo.wsConnected ? 'ON' : 'OFF'}</div>
			<div>Room: {debugInfo.currentRoom || 'None'}</div>
		</div>
		<div class="mt-2 grid grid-cols-3 gap-4">
			<div>Updates: {updateCount}</div>
			<div>State Syncs: {stateSyncCount}</div>
			<div>Errors: {errorCount}</div>
		</div>
		<div class="mt-2">Last Update: {lastUpdate ? lastUpdate.toLocaleTimeString() : 'Never'}</div>
		{#if error}
			<div class="mt-2 text-red-400">Error: {error}</div>
		{/if}
	</div>

	{#if !connected}
		<!-- Connection Section -->
		<div class="rounded border p-6">
			<h2 class="mb-4 font-mono text-lg font-semibold">Connect to Robotics Room</h2>

			<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
				<div>
					<label for="roomId" class="mb-1 block font-mono text-sm font-medium text-gray-700">
						Room ID
					</label>
					<input
						id="roomId"
						type="text"
						bind:value={roomId}
						placeholder="Enter room ID to monitor"
						class="w-full rounded border border-gray-300 px-3 py-2 font-mono focus:border-blue-500 focus:ring-blue-500"
					/>
				</div>
				<div>
					<label for="participantId" class="mb-1 block font-mono text-sm font-medium text-gray-700">
						Participant ID
					</label>
					<input
						id="participantId"
						type="text"
						bind:value={participantId}
						placeholder="Your participant ID"
						class="w-full rounded border border-gray-300 px-3 py-2 font-mono focus:border-blue-500 focus:ring-blue-500"
					/>
				</div>
			</div>

			<div class="mt-4">
				<button
					onclick={connectConsumer}
					disabled={connecting || !roomId.trim() || !participantId.trim()}
					class={[
						'rounded border px-4 py-2 font-mono',
						connecting || !roomId.trim() || !participantId.trim()
							? 'bg-gray-200 text-gray-500'
							: 'bg-blue-600 text-white hover:bg-blue-700'
					]}
				>
					{connecting ? 'Connecting...' : 'Join as Observer'}
				</button>
			</div>

			{#if error}
				<div class="mt-4 rounded border border-red-200 bg-red-50 p-4">
					<p class="font-mono text-sm text-red-700">{error}</p>
				</div>
			{/if}
		</div>
	{:else}
		<!-- Monitoring Interface -->
		<div class="space-y-6">
			<!-- Status Overview -->
			<div class="grid grid-cols-2 gap-4 md:grid-cols-4">
				<div class="rounded border p-4 text-center">
					<div class="font-mono text-2xl font-bold text-blue-600">{updateCount}</div>
					<div class="font-mono text-sm text-gray-500">Joint Updates</div>
				</div>
				<div class="rounded border p-4 text-center">
					<div class="font-mono text-2xl font-bold text-purple-600">{stateSyncCount}</div>
					<div class="font-mono text-sm text-gray-500">State Syncs</div>
				</div>
				<div class="rounded border p-4 text-center">
					<div class="font-mono text-2xl font-bold text-red-600">{errorCount}</div>
					<div class="font-mono text-sm text-gray-500">Errors</div>
				</div>
				<div class="rounded border p-4 text-center">
					<div class="font-mono text-2xl font-bold text-green-600">
						{lastUpdate ? lastUpdate.toLocaleTimeString() : 'N/A'}
					</div>
					<div class="font-mono text-sm text-gray-500">Last Update</div>
				</div>
			</div>

			<!-- Robot State Display -->
			<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
				<!-- Robot Visualization -->
				<div class="rounded border p-4 lg:col-span-2">
					<h2 class="mb-3 font-mono text-lg font-semibold">Robot Arm Visualization</h2>

					<div class="aspect-video rounded border bg-gray-50 p-4">
						<div class="flex h-full items-center justify-center">
							<div class="text-center">
								<div class="mb-4 text-6xl">🦾</div>
								<p class="font-mono text-gray-600">3D Robot Visualization</p>
								<p class="font-mono text-xs text-gray-500">Live joint positions from producer</p>
							</div>
						</div>
					</div>

					<!-- Current Joint Values -->
					{#if Object.keys(currentJoints).length > 0}
						<div class="mt-4 grid grid-cols-2 gap-4 md:grid-cols-3">
							{#each Object.entries(currentJoints) as [name, value]}
								<div class="text-center">
									<div class="font-mono text-sm text-gray-500 capitalize">
										{name.replace(/([A-Z])/g, ' $1').replace(/^./, (str) => str.toUpperCase())}
									</div>
									<div class="font-mono text-lg font-bold">{value.toFixed(1)}°</div>
								</div>
							{/each}
						</div>
					{/if}
				</div>

				<!-- Session Info & Controls -->
				<div class="space-y-6">
					<!-- Session Info -->
					<div class="rounded border p-4">
						<h2 class="mb-3 font-mono text-lg font-semibold">Session Info</h2>
						<div class="grid grid-cols-1 gap-2 font-mono text-sm">
							<div><span class="text-gray-500">Workspace:</span> {workspaceId}</div>
							<div><span class="text-gray-500">Room:</span> {roomId}</div>
							<div><span class="text-gray-500">ID:</span> {participantId}</div>
							<div><span class="text-gray-500">Role:</span> Consumer</div>
							<div><span class="text-gray-500">Active Joints:</span> {Object.keys(currentJoints).length}</div>
						</div>
						<div class="mt-4 flex space-x-3">
							<button
								onclick={clearHistory}
								class="rounded border bg-gray-100 px-3 py-2 font-mono text-sm hover:bg-gray-200"
							>
								Clear History
							</button>
							<button
								onclick={exitSession}
								class="rounded border bg-gray-100 px-3 py-2 font-mono text-sm hover:bg-gray-200"
							>
								🚪 Exit Session
							</button>
						</div>
					</div>

					<!-- Joint Trends -->
					{#if Object.keys(jointTrends).length > 0}
						<div class="rounded border p-4">
							<h2 class="mb-3 font-mono text-lg font-semibold">Joint Trends</h2>
							<div class="max-h-48 space-y-2 overflow-y-auto">
								{#each Object.entries(jointTrends) as [name, values]}
									<div class="rounded bg-gray-50 p-2">
										<div class="flex items-center justify-between">
											<span class="font-mono text-xs text-gray-600 capitalize">
												{name.replace(/([A-Z])/g, ' $1').replace(/^./, (str) => str.toUpperCase())}
											</span>
											<span class="font-mono text-xs font-bold">
												{values[values.length - 1]?.toFixed(1) || '0.0'}°
											</span>
										</div>
										<div class="mt-1 flex h-4 items-end space-x-1">
											{#each values as value, i}
												<div
													class="w-2 bg-blue-300"
													style="height: {Math.abs(value) / 180 * 100}%"
													title="{value.toFixed(1)}°"
												></div>
											{/each}
										</div>
									</div>
								{/each}
							</div>
						</div>
					{/if}
				</div>
			</div>

			<!-- Real-time Updates -->
			<div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
				<!-- Joint Updates History -->
				<div class="rounded border p-4">
					<h2 class="mb-3 font-mono text-lg font-semibold">Recent Joint Updates</h2>
					<div class="max-h-64 space-y-2 overflow-y-auto">
						{#each jointHistory.slice(0, 10) as update}
							<div class="rounded border-l-4 border-blue-200 bg-gray-50 p-2">
								<div class="flex items-center justify-between">
									<span class="font-mono text-xs text-gray-500">{update.timestamp}</span>
									<span class="font-mono text-xs text-blue-600">JOINT_UPDATE</span>
								</div>
								<div class="mt-1 text-sm">
									<span class="font-mono text-gray-700">
										{update.joints.length} joint(s): 
										{update.joints.map(j => `${j.name}=${j.value.toFixed(1)}°`).join(', ')}
									</span>
								</div>
							</div>
						{:else}
							<p class="py-4 text-center font-mono text-sm text-gray-500">No joint updates received yet</p>
						{/each}
					</div>
				</div>

				<!-- State Sync History -->
				<div class="rounded border p-4">
					<h2 class="mb-3 font-mono text-lg font-semibold">State Sync History</h2>
					<div class="max-h-64 space-y-2 overflow-y-auto">
						{#each stateHistory as state}
							<div class="rounded border-l-4 border-purple-200 bg-gray-50 p-2">
								<div class="flex items-center justify-between">
									<span class="font-mono text-xs text-gray-500">{state.timestamp}</span>
									<span class="font-mono text-xs text-purple-600">STATE_SYNC</span>
								</div>
								<div class="mt-1 text-sm">
									<div class="font-mono text-gray-700">
										{Object.keys(state.state).length} joints synchronized
									</div>
								</div>
							</div>
						{:else}
							<p class="py-4 text-center font-mono text-sm text-gray-500">
								No state syncs received yet
							</p>
						{/each}
					</div>
				</div>
			</div>

			<!-- Error History -->
			{#if errorHistory.length > 0}
				<div class="rounded border p-4">
					<h2 class="mb-3 font-mono text-lg font-semibold">Recent Errors</h2>
					<div class="max-h-32 space-y-2 overflow-y-auto">
						{#each errorHistory as error}
							<div class="rounded border-l-4 border-red-200 bg-red-50 p-2">
								<div class="flex items-center justify-between">
									<span class="font-mono text-xs text-gray-500">{error.timestamp}</span>
									<span class="font-mono text-xs text-red-600">ERROR</span>
								</div>
								<div class="mt-1 font-mono text-sm text-red-700">
									{error.message}
								</div>
							</div>
						{/each}
					</div>
				</div>
			{/if}
		</div>
	{/if}
</div> 