import React, { useState, useCallback, useEffect } from 'react'
import mcpService from '../../services/mcpService'
import MCPStatusBanner from '../../components/MCPStatusBanner'
import LaunchControls from '../../components/LaunchControls'
// Advanced environment management state
const advancedEnvironmentState = {
currentWorld: {
id: 'warehouse_alpha',
name: 'Warehouse Alpha',
type: 'industrial',
status: 'loaded',
size: { x: 50, y: 30, z: 20 },
lighting: {
ambient: 0.3,
directional: 0.8,
shadows: true,
fog: { enabled: true, density: 0.01, color: '#87CEEB' }
},
physics: {
gravity: -9.81,
timeScale: 1.0,
collisionDetection: true
}
},
availableWorlds: [
{ id: 'warehouse_alpha', name: 'Warehouse Alpha', type: 'industrial', status: 'loaded' },
{ id: 'office_beta', name: 'Office Beta', type: 'commercial', status: 'available' },
{ id: 'lab_gamma', name: 'Lab Gamma', type: 'research', status: 'syncing' },
{ id: 'outdoor_delta', name: 'Outdoor Delta', type: 'outdoor', status: 'downloading' }
],
unityIntegration: {
connected: true,
version: '2022.3.15f1',
scenes: ['MainScene', 'TestScene', 'DebugScene'],
activeScene: 'MainScene',
gameObjects: 1247,
renderPipeline: 'URP'
},
marbleWorlds: {
active: true,
worldsGenerated: 23,
currentSeed: 'alpha-47-beta',
aiGenerated: true,
quality: 'ultra',
size: 'large'
},
assets: {
models: 456,
textures: 892,
materials: 234,
prefabs: 67,
animations: 123
},
performance: {
fps: 60,
drawCalls: 1247,
triangles: 456789,
memory: 1.2, // GB
gpuUsage: 45
}
}
export default function EnvironmentsPage() {
console.log('Advanced Environments Page loading...')
const [environmentState, setEnvironmentState] = useState(advancedEnvironmentState)
const [selectedWorld, setSelectedWorld] = useState(environmentState.currentWorld.id)
const [showUnityPanel, setShowUnityPanel] = useState(true)
const [showPerformance, setShowPerformance] = useState(false)
const [mcpConnected, setMcpConnected] = useState(false)
const [usingMockData, setUsingMockData] = useState(true)
useEffect(() => {
const checkConnection = async () => {
const healthy = await mcpService.checkHealth('unity3d')
setMcpConnected(healthy)
setUsingMockData(!healthy)
}
checkConnection()
const interval = setInterval(checkConnection, 10000)
return () => clearInterval(interval)
}, [])
const loadWorld = useCallback(async (worldId: string) => {
console.log('Loading world:', worldId)
if (mcpConnected) {
try {
const result = await mcpService.unity3dCallTool('load_scene', {
scene_name: worldId
})
if (result.success) {
setEnvironmentState(prev => ({
...prev,
currentWorld: prev.availableWorlds.find(w => w.id === worldId) || prev.currentWorld
}))
} else {
console.warn(`MCP load world failed: ${result.error}`)
}
} catch (error) {
console.error('Error loading world via MCP:', error)
}
} else {
// Mock fallback
setTimeout(() => {
setEnvironmentState(prev => ({
...prev,
currentWorld: prev.availableWorlds.find(w => w.id === worldId) || prev.currentWorld
}))
}, 2000)
}
}, [mcpConnected])
const updateLighting = useCallback((property: string, value: any) => {
setEnvironmentState(prev => ({
...prev,
currentWorld: {
...prev.currentWorld,
lighting: {
...prev.currentWorld.lighting,
[property]: value
}
}
}))
}, [])
const updatePhysics = useCallback((property: string, value: any) => {
setEnvironmentState(prev => ({
...prev,
currentWorld: {
...prev.currentWorld,
physics: {
...prev.currentWorld.physics,
[property]: value
}
}
}))
}, [])
return (
<div style={{
minHeight: '100vh',
backgroundColor: '#0f172a',
color: '#f8fafc',
padding: '24px',
fontFamily: 'system-ui, -apple-system, sans-serif'
}}>
<div style={{ maxWidth: '1400px', margin: '0 auto' }}>
{/* MCP Status Banner */}
<MCPStatusBanner serverName="unity3d" displayName="Unity3D" />
{/* Header */}
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: '32px',
padding: '24px',
backgroundColor: '#1e293b',
borderRadius: '16px',
border: '1px solid #334155'
}}>
<div style={{ display: 'flex', alignItems: 'center', gap: '20px' }}>
<div style={{
width: '64px',
height: '64px',
backgroundColor: '#10b981',
borderRadius: '16px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '32px'
}}>
๐
</div>
<div>
<h1 style={{
fontSize: '32px',
fontWeight: 'bold',
color: '#f8fafc',
marginBottom: '4px'
}}>Advanced Environment Management</h1>
<p style={{ color: '#94a3b8' }}>Unity3D integration, World Labs Marble, and 3D scene orchestration</p>
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
<div style={{
padding: '8px 16px',
backgroundColor: environmentState.performance.fps >= 50 ? '#10b981' : '#f59e0b',
color: 'white',
borderRadius: '20px',
fontSize: '12px',
fontWeight: '500'
}}>
๐ฎ {environmentState.performance.fps} FPS
</div>
<button
onClick={() => setShowPerformance(!showPerformance)}
style={{
padding: '8px 16px',
backgroundColor: showPerformance ? '#3b82f6' : '#6b7280',
color: 'white',
border: 'none',
borderRadius: '6px',
fontSize: '12px',
cursor: 'pointer'
}}
>
๐ {showPerformance ? 'Hide' : 'Show'} Metrics
</button>
</div>
</div>
{/* Performance Metrics */}
{showPerformance && (
<div style={{
marginBottom: '24px',
padding: '20px',
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155'
}}>
<h3 style={{ fontSize: '16px', fontWeight: '600', color: '#f8fafc', marginBottom: '12px' }}>
โก Performance Metrics
</h3>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))', gap: '16px' }}>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#3b82f6' }}>
{environmentState.performance.fps}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>FPS</div>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#10b981' }}>
{environmentState.performance.drawCalls.toLocaleString()}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Draw Calls</div>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#f59e0b' }}>
{(environmentState.performance.triangles / 1000).toFixed(0)}K
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Triangles</div>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#8b5cf6' }}>
{environmentState.performance.memory}GB
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Memory</div>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#ec4899' }}>
{environmentState.performance.gpuUsage}%
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>GPU</div>
</div>
</div>
</div>
)}
{/* Main Content Grid */}
<div style={{
display: 'grid',
gridTemplateColumns: '1fr 400px',
gap: '24px'
}}>
{/* Left Panel - World Visualization */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
{/* 3D World Viewer */}
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '24px',
height: '500px'
}}>
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: '16px'
}}>
<h3 style={{ fontSize: '18px', fontWeight: '600', color: '#f8fafc' }}>
๐๏ธ 3D World Viewer - {environmentState.currentWorld.name}
</h3>
<div style={{ display: 'flex', gap: '8px' }}>
<button style={{
padding: '6px 12px',
backgroundColor: '#3b82f6',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}>๐</button>
<button style={{
padding: '6px 12px',
backgroundColor: '#6b7280',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}>๐ท</button>
</div>
</div>
{/* 3D Scene Placeholder */}
<div style={{
height: '350px',
backgroundColor: '#0f172a',
borderRadius: '8px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
border: '2px dashed #475569'
}}>
<div style={{ textAlign: 'center', color: '#94a3b8' }}>
<div style={{ fontSize: '64px', marginBottom: '16px' }}>๐</div>
<div style={{ fontSize: '18px', fontWeight: '500', marginBottom: '8px' }}>
Unity3D Scene Active
</div>
<div style={{ fontSize: '14px' }}>
{environmentState.currentWorld.size.x}m ร {environmentState.currentWorld.size.y}m ร {environmentState.currentWorld.size.z}m
</div>
<div style={{ fontSize: '12px', marginTop: '8px', color: '#64748b' }}>
{environmentState.unityIntegration.gameObjects} GameObjects โข {environmentState.assets.models} Models
</div>
</div>
</div>
{/* Scene Controls */}
<div style={{
display: 'flex',
gap: '8px',
marginTop: '16px',
flexWrap: 'wrap'
}}>
<button style={{
padding: '6px 12px',
backgroundColor: '#10b981',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}>โถ๏ธ Play</button>
<button style={{
padding: '6px 12px',
backgroundColor: '#f59e0b',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}>โธ๏ธ Pause</button>
<button style={{
padding: '6px 12px',
backgroundColor: '#8b5cf6',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}>๐พ Save Scene</button>
<button style={{
padding: '6px 12px',
backgroundColor: '#6b7280',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}>๐ง Inspector</button>
</div>
</div>
{/* World Labs Marble */}
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '24px'
}}>
<h3 style={{ fontSize: '18px', fontWeight: '600', color: '#f8fafc', marginBottom: '16px' }}>
๐จ World Labs Marble - AI Environment Generation
</h3>
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))',
gap: '12px',
marginBottom: '16px'
}}>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '24px', fontWeight: 'bold', color: '#10b981' }}>
{environmentState.marbleWorlds.worldsGenerated}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Worlds Generated</div>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '16px', fontWeight: 'bold', color: '#3b82f6' }}>
{environmentState.marbleWorlds.quality}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Quality</div>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '16px', fontWeight: 'bold', color: '#f59e0b' }}>
{environmentState.marbleWorlds.size}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Size</div>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '16px', fontWeight: 'bold', color: '#8b5cf6' }}>
{environmentState.marbleWorlds.currentSeed.split('-')[0]}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Seed</div>
</div>
</div>
<div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
<button style={{
padding: '8px 16px',
backgroundColor: '#10b981',
color: 'white',
border: 'none',
borderRadius: '6px',
fontSize: '12px',
cursor: 'pointer'
}}>๐ฒ Generate New World</button>
<button style={{
padding: '8px 16px',
backgroundColor: '#3b82f6',
color: 'white',
border: 'none',
borderRadius: '6px',
fontSize: '12px',
cursor: 'pointer'
}}>๐ Regenerate</button>
<button style={{
padding: '8px 16px',
backgroundColor: '#8b5cf6',
color: 'white',
border: 'none',
borderRadius: '6px',
fontSize: '12px',
cursor: 'pointer'
}}>๐พ Export World</button>
</div>
</div>
</div>
{/* Right Panel - Controls & Settings */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
{/* Launch Controls */}
<LaunchControls
appId="unity3d"
appName="Unity3D"
projectPath={true}
onStatusChange={(running) => {
// Update UI based on app status if needed
}}
/>
{/* World Selection */}
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '24px'
}}>
<h3 style={{ fontSize: '18px', fontWeight: '600', color: '#f8fafc', marginBottom: '16px' }}>
๐ World Library
</h3>
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
{environmentState.availableWorlds.map(world => (
<div
key={world.id}
onClick={() => {
setSelectedWorld(world.id)
if (world.status === 'available') {
loadWorld(world.id)
}
}}
style={{
padding: '12px 16px',
backgroundColor: selectedWorld === world.id ? '#3b82f6' : '#0f172a',
borderRadius: '6px',
cursor: world.status === 'available' ? 'pointer' : 'not-allowed',
border: '1px solid #334155',
opacity: world.status === 'available' ? 1 : 0.6
}}
>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<div>
<div style={{ fontSize: '14px', fontWeight: '500', color: '#f8fafc' }}>
{world.name}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>
{world.type} โข {world.status}
</div>
</div>
<div style={{
padding: '4px 8px',
borderRadius: '12px',
fontSize: '10px',
fontWeight: '500',
backgroundColor: world.status === 'loaded' ? '#10b981' :
world.status === 'available' ? '#3b82f6' :
world.status === 'syncing' ? '#f59e0b' : '#6b7280',
color: 'white'
}}>
{world.status.toUpperCase()}
</div>
</div>
</div>
))}
</div>
</div>
{/* Unity Integration Panel */}
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '24px'
}}>
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: '16px'
}}>
<h3 style={{ fontSize: '18px', fontWeight: '600', color: '#f8fafc' }}>
๐ฎ Unity Integration
</h3>
<button
onClick={() => setShowUnityPanel(!showUnityPanel)}
style={{
padding: '4px 8px',
backgroundColor: showUnityPanel ? '#3b82f6' : '#6b7280',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '10px',
cursor: 'pointer'
}}
>
{showUnityPanel ? 'Hide' : 'Show'}
</button>
</div>
{showUnityPanel && (
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Status</span>
<span style={{
padding: '4px 8px',
backgroundColor: environmentState.unityIntegration.connected ? '#10b981' : '#dc2626',
color: 'white',
borderRadius: '12px',
fontSize: '10px',
fontWeight: '500'
}}>
{environmentState.unityIntegration.connected ? 'Connected' : 'Disconnected'}
</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Version</span>
<span style={{ color: '#f8fafc', fontSize: '12px', fontWeight: '500' }}>
{environmentState.unityIntegration.version}
</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Active Scene</span>
<span style={{ color: '#f8fafc', fontSize: '12px', fontWeight: '500' }}>
{environmentState.unityIntegration.activeScene}
</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>GameObjects</span>
<span style={{ color: '#f8fafc', fontSize: '12px', fontWeight: '500' }}>
{environmentState.unityIntegration.gameObjects.toLocaleString()}
</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Pipeline</span>
<span style={{ color: '#f8fafc', fontSize: '12px', fontWeight: '500' }}>
{environmentState.unityIntegration.renderPipeline}
</span>
</div>
</div>
)}
</div>
{/* Environment Settings */}
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '24px'
}}>
<h3 style={{ fontSize: '18px', fontWeight: '600', color: '#f8fafc', marginBottom: '16px' }}>
โ๏ธ Environment Settings
</h3>
{/* Lighting Controls */}
<div style={{ marginBottom: '20px' }}>
<h4 style={{ fontSize: '14px', fontWeight: '500', color: '#f8fafc', marginBottom: '8px' }}>
๐ก Lighting
</h4>
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Ambient</span>
<input
type="range"
min="0"
max="1"
step="0.1"
value={environmentState.currentWorld.lighting.ambient}
onChange={(e) => updateLighting('ambient', parseFloat(e.target.value))}
style={{ width: '60px' }}
/>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Directional</span>
<input
type="range"
min="0"
max="1"
step="0.1"
value={environmentState.currentWorld.lighting.directional}
onChange={(e) => updateLighting('directional', parseFloat(e.target.value))}
style={{ width: '60px' }}
/>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<input
type="checkbox"
checked={environmentState.currentWorld.lighting.shadows}
onChange={(e) => updateLighting('shadows', e.target.checked)}
/>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Shadows</span>
</div>
</div>
</div>
{/* Physics Controls */}
<div>
<h4 style={{ fontSize: '14px', fontWeight: '500', color: '#f8fafc', marginBottom: '8px' }}>
โ๏ธ Physics
</h4>
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Gravity</span>
<span style={{ color: '#f8fafc', fontSize: '12px' }}>
{environmentState.currentWorld.physics.gravity.toFixed(2)}
</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Time Scale</span>
<input
type="range"
min="0.1"
max="2"
step="0.1"
value={environmentState.currentWorld.physics.timeScale}
onChange={(e) => updatePhysics('timeScale', parseFloat(e.target.value))}
style={{ width: '60px' }}
/>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<input
type="checkbox"
checked={environmentState.currentWorld.physics.collisionDetection}
onChange={(e) => updatePhysics('collisionDetection', e.target.checked)}
/>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Collision Detection</span>
</div>
</div>
</div>
</div>
{/* Asset Management */}
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '24px'
}}>
<h3 style={{ fontSize: '18px', fontWeight: '600', color: '#f8fafc', marginBottom: '16px' }}>
๐ฆ Asset Management
</h3>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px' }}>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#3b82f6' }}>
{environmentState.assets.models}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Models</div>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#10b981' }}>
{environmentState.assets.textures}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Textures</div>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#f59e0b' }}>
{environmentState.assets.materials}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Materials</div>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#8b5cf6' }}>
{environmentState.assets.prefabs}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Prefabs</div>
</div>
</div>
<div style={{ display: 'flex', gap: '8px', marginTop: '16px', flexWrap: 'wrap' }}>
<button style={{
padding: '6px 12px',
backgroundColor: '#3b82f6',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}>๐ค Import</button>
<button style={{
padding: '6px 12px',
backgroundColor: '#10b981',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}>๐ฅ Export</button>
<button style={{
padding: '6px 12px',
backgroundColor: '#6b7280',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}>๐๏ธ Organize</button>
</div>
</div>
</div>
</div>
</div>
</div>
)
}