import React, { useState, useEffect } from 'react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Progress } from '@/components/ui/progress';
import { AlertCircle, Eye, EyeOff, Wifi, Activity } from 'lucide-react';
import { Alert, AlertDescription } from '@/components/ui/alert';
interface HueSensor {
sensor_id: string;
name: string;
location: string;
enabled: boolean;
battery?: number;
last_movement?: number;
movement_count?: number;
presence?: boolean;
reachable?: boolean;
}
interface HueRobot {
robot_id: string;
robot_type: 'hue';
connected: boolean;
sensors?: HueSensor[];
zones?: any;
}
interface HueControlsProps {
robot: HueRobot;
onCommand: (robotId: string, command: any) => void;
}
export function HueControls({ robot, onCommand }: HueControlsProps) {
const [movementEvents, setMovementEvents] = useState<any[]>([]);
const [lastUpdate, setLastUpdate] = useState<Date>(new Date());
const sendCommand = (action: string, params: any = {}) => {
onCommand(robot.robot_id, {
action,
robot_id: robot.robot_id,
...params
});
};
// Auto-refresh movement events every 30 seconds
useEffect(() => {
const interval = setInterval(() => {
if (robot.connected) {
sendCommand('hue_get_movement_events');
setLastUpdate(new Date());
}
}, 30000);
return () => clearInterval(interval);
}, [robot.connected]);
// Get movement events when component mounts or robot connects
useEffect(() => {
if (robot.connected) {
sendCommand('hue_get_movement_events');
sendCommand('hue_get_sensor_status');
}
}, [robot.connected]);
const getMovementStatus = (sensor: HueSensor) => {
if (!sensor.last_movement) return { status: 'No activity', color: 'text-gray-500' };
const timeSince = Date.now() / 1000 - sensor.last_movement;
if (timeSince < 60) return { status: 'Active now', color: 'text-green-500' };
if (timeSince < 300) return { status: `${Math.floor(timeSince / 60)}m ago`, color: 'text-yellow-500' };
if (timeSince < 3600) return { status: `${Math.floor(timeSince / 3600)}h ago`, color: 'text-orange-500' };
return { status: 'Inactive', color: 'text-red-500' };
};
const getBatteryStatus = (battery?: number) => {
if (!battery) return { level: 'Unknown', color: 'text-gray-500' };
if (battery > 75) return { level: `${battery}%`, color: 'text-green-500' };
if (battery > 50) return { level: `${battery}%`, color: 'text-yellow-500' };
if (battery > 25) return { level: `${battery}%`, color: 'text-orange-500' };
return { level: `${battery}%`, color: 'text-red-500' };
};
return (
<Card className="w-full">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Activity className="w-5 h-5 text-purple-500" />
Philips Hue Bridge Pro - HomeAware
</CardTitle>
<CardDescription>
RF-based movement detection without cameras or microphones
</CardDescription>
</CardHeader>
<CardContent>
<Tabs defaultValue="sensors" className="w-full">
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="sensors">Sensors</TabsTrigger>
<TabsTrigger value="movement">Movement</TabsTrigger>
<TabsTrigger value="zones">Zones</TabsTrigger>
</TabsList>
<TabsContent value="sensors" className="space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-medium">HomeAware Sensors</h3>
<Button
onClick={() => {
sendCommand('hue_get_sensor_status');
setLastUpdate(new Date());
}}
variant="outline"
size="sm"
disabled={!robot.connected}
>
🔄 Refresh
</Button>
</div>
{robot.sensors && robot.sensors.length > 0 ? (
<div className="grid gap-4">
{robot.sensors.map((sensor) => {
const movementStatus = getMovementStatus(sensor);
const batteryStatus = getBatteryStatus(sensor.battery);
return (
<Card key={sensor.sensor_id} className="p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="flex items-center gap-2">
{sensor.presence ? (
<Eye className="w-5 h-5 text-green-500" />
) : (
<EyeOff className="w-5 h-5 text-gray-400" />
)}
<div>
<h4 className="font-medium">{sensor.name}</h4>
<p className="text-sm text-gray-600">{sensor.location}</p>
</div>
</div>
</div>
<div className="flex items-center gap-2">
<Badge variant={sensor.enabled ? "default" : "secondary"}>
{sensor.enabled ? "Enabled" : "Disabled"}
</Badge>
<Badge variant={sensor.reachable ? "default" : "destructive"}>
{sensor.reachable ? "Online" : "Offline"}
</Badge>
</div>
</div>
<div className="mt-3 grid grid-cols-2 gap-4">
<div>
<p className="text-sm text-gray-600">Movement</p>
<p className={`font-medium ${movementStatus.color}`}>
{movementStatus.status}
</p>
{sensor.movement_count !== undefined && (
<p className="text-xs text-gray-500">
{sensor.movement_count} total detections
</p>
)}
</div>
<div>
<p className="text-sm text-gray-600">Battery</p>
<p className={`font-medium ${batteryStatus.color}`}>
{batteryStatus.level}
</p>
{sensor.battery && (
<Progress value={sensor.battery} className="mt-1 h-2" />
)}
</div>
</div>
</Card>
);
})}
</div>
) : (
<div className="text-center py-8 text-gray-500">
<Wifi className="w-12 h-12 mx-auto mb-4 opacity-50" />
<p>No HomeAware sensors detected</p>
<p className="text-sm">Make sure HomeAware is enabled in the Philips Hue app</p>
</div>
)}
</TabsContent>
<TabsContent value="movement" className="space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-medium">Movement Events</h3>
<div className="flex items-center gap-2">
<Button
onClick={() => sendCommand('hue_get_movement_events')}
variant="outline"
size="sm"
disabled={!robot.connected}
>
🔄 Refresh
</Button>
<span className="text-sm text-gray-500">
Last update: {lastUpdate.toLocaleTimeString()}
</span>
</div>
</div>
<div className="bg-gray-50 rounded-lg p-4">
<div className="flex items-center gap-2 mb-3">
<Activity className="w-5 h-5 text-purple-500" />
<span className="font-medium">RF Movement Detection</span>
<Badge variant="outline" className="bg-purple-50">
Privacy-First
</Badge>
</div>
<div className="space-y-2 text-sm text-gray-600">
<p>• <strong>No cameras or microphones</strong> - Uses only Zigbee signal analysis</p>
<p>• <strong>Works in complete darkness</strong> - RF detection doesn't need light</p>
<p>• <strong>Through-wall sensing</strong> - Can detect movement behind walls</p>
<p>• <strong>Passive monitoring</strong> - Uses existing smart home signals</p>
</div>
</div>
<Alert>
<AlertCircle className="h-4 w-4" />
<AlertDescription>
Movement events are automatically refreshed every 30 seconds.
The system learns your home's RF patterns over the first 24-48 hours.
</AlertDescription>
</Alert>
</TabsContent>
<TabsContent value="zones" className="space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-medium">Detection Zones</h3>
<Button
onClick={() => sendCommand('hue_get_movement_zones')}
variant="outline"
size="sm"
disabled={!robot.connected}
>
🔄 Refresh Zones
</Button>
</div>
{robot.zones && robot.zones.zones ? (
<div className="space-y-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{Object.entries(robot.zones.zones).map(([zoneName, zoneData]: [string, any]) => (
<Card key={zoneName} className="p-4">
<h4 className="font-medium mb-2">{zoneName}</h4>
<div className="space-y-1 text-sm text-gray-600">
<p>• Coverage: {zoneData.coverage_area || 'Room-level'}</p>
<p>• Method: {zoneData.detection_method || 'RF Analysis'}</p>
{zoneData.last_activity && (
<p>• Last activity: {new Date(zoneData.last_activity * 1000).toLocaleString()}</p>
)}
<p>• Total detections: {zoneData.activity_count || 0}</p>
</div>
</Card>
))}
</div>
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
<h4 className="font-medium text-blue-900 mb-2">Zone-Based Automation</h4>
<p className="text-sm text-blue-800">
Configure robot behaviors based on movement in specific zones.
For example, start cleaning when movement is detected in the kitchen,
or pause operations when someone enters a workspace.
</p>
</div>
</div>
) : (
<div className="text-center py-8 text-gray-500">
<Activity className="w-12 h-12 mx-auto mb-4 opacity-50" />
<p>No detection zones configured</p>
<p className="text-sm">Zones are automatically created based on sensor locations</p>
</div>
)}
</TabsContent>
</Tabs>
{!robot.connected && (
<Alert className="mt-4">
<AlertCircle className="h-4 w-4" />
<AlertDescription>
Hue Bridge Pro is not connected. Please check the robotics MCP server configuration
and ensure the bridge is powered on and accessible on the network.
</AlertDescription>
</Alert>
)}
</CardContent>
</Card>
);
}