import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mirror_core/mirror_core.dart'; import 'package:mirror_ui/mirror_ui.dart'; import 'package:mirror_protocol/mirror_protocol.dart'; import '../providers/connection_provider.dart'; import '../providers/ha_provider.dart'; import '../providers/update_provider.dart'; import 'settings_screen.dart'; class RemoteDashboard extends ConsumerWidget { const RemoteDashboard({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final haState = ref.watch(haEntitiesProvider); return SingleChildScrollView( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Mirror OS', style: Theme.of(context).textTheme.headlineMedium), IconButton( icon: const Icon(Icons.settings), tooltip: 'Settings', onPressed: () { Navigator.of(context).push( MaterialPageRoute(builder: (_) => const SettingsScreen()), ); }, ), ], ), const SizedBox(height: 16), const UpdateBanner(), const SizedBox(height: 16), Text( 'Quick Actions', style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: MirrorTheme.textMuted, ), ), const SizedBox(height: 16), _ActionCard( icon: Icons.fitness_center, title: 'Start Workout', subtitle: 'Browse your video library', color: MirrorTheme.accent, onTap: () { ref.read(connectionProvider.notifier).send( NavigateCommand(target: ScreenType.workout), ); ref.read(connectionProvider.notifier).send( WorkoutCommand( action: WorkoutAction.browse, payload: {'path': '', 'filter': 'all'}, ), ); }, ), const SizedBox(height: 12), _ActionCard( icon: Icons.music_note, title: 'Media', subtitle: 'Play music or video', color: MirrorTheme.success, onTap: () { ref.read(connectionProvider.notifier).send( NavigateCommand(target: ScreenType.media), ); }, ), const SizedBox(height: 12), _ActionCard( icon: Icons.nightlight_round, title: 'Standby', subtitle: 'Turn off the display', color: MirrorTheme.textMuted, onTap: () { ref.read(connectionProvider.notifier).send( NavigateCommand(target: ScreenType.standby), ); }, ), // --- Home Assistant Device Controls --- const SizedBox(height: 32), Text( 'Home Assistant', style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: MirrorTheme.textMuted, ), ), const SizedBox(height: 16), haState.when( loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => Text('HA Error: $e', style: TextStyle(color: MirrorTheme.danger, fontSize: 13)), data: (data) { if (data.error != null) { return Container( width: double.infinity, padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: MirrorTheme.surface, borderRadius: BorderRadius.circular(12), ), child: Column( children: [ Icon(Icons.home, size: 36, color: MirrorTheme.textMuted), const SizedBox(height: 8), Text(data.error!, style: TextStyle(color: MirrorTheme.textMuted, fontSize: 13)), ], ), ); } return _HaDeviceControls(entities: data.entities); }, ), // --- Scenes --- const SizedBox(height: 24), Text( 'Scenes', style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: MirrorTheme.textMuted, ), ), const SizedBox(height: 12), _HaSceneButtons(), ], ), ); } } // --- HA Device Controls --- class _HaDeviceControls extends ConsumerWidget { final List entities; const _HaDeviceControls({required this.entities}); @override Widget build(BuildContext context, WidgetRef ref) { final toggleable = entities.where((e) { return e.entityId.startsWith('light.') || e.entityId.startsWith('switch.'); }).toList(); if (toggleable.isEmpty) { return Container( width: double.infinity, padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: MirrorTheme.surface, borderRadius: BorderRadius.circular(12), ), child: Column( children: [ Icon(Icons.lightbulb_outline, size: 36, color: MirrorTheme.textMuted), const SizedBox(height: 8), Text( 'No lights or switches found', style: TextStyle(color: MirrorTheme.textMuted, fontSize: 13), ), ], ), ); } return Column( children: toggleable.map((entity) { final friendlyName = entity.attributes['friendly_name'] as String? ?? entity.entityId.split('.').last; final isOn = entity.state == 'on'; final isLight = entity.entityId.startsWith('light.'); return Container( margin: const EdgeInsets.only(bottom: 8), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( color: MirrorTheme.surface, borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Icon( isLight ? Icons.lightbulb : Icons.power_settings_new, color: isOn ? MirrorTheme.accent : MirrorTheme.textMuted, size: 24, ), const SizedBox(width: 12), Expanded( child: Text(friendlyName, style: const TextStyle(fontSize: 14)), ), Switch( value: isOn, onChanged: (_) { ref.read(haEntitiesProvider.notifier).toggleEntity(entity.entityId); }, ), ], ), ); }).toList(), ); } } // --- Scene Buttons --- class _HaSceneButtons extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final haState = ref.watch(haEntitiesProvider).valueOrNull; if (haState == null || haState.error != null) return const SizedBox.shrink(); final scenes = haState.entities .where((e) => e.entityId.startsWith('scene.')) .toList(); if (scenes.isEmpty) return const SizedBox.shrink(); return Wrap( spacing: 8, runSpacing: 8, children: scenes.map((scene) { final name = scene.attributes['friendly_name'] as String? ?? scene.entityId.split('.').last.replaceAll('_', ' '); return ActionChip( avatar: const Icon(Icons.play_arrow, size: 18), label: Text(name), onPressed: () { ref.read(haEntitiesProvider.notifier).callScene(scene.entityId); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Activating $name...')), ); }, ); }).toList(), ); } } class _ActionCard extends StatelessWidget { final IconData icon; final String title; final String subtitle; final Color color; final VoidCallback onTap; const _ActionCard({ required this.icon, required this.title, required this.subtitle, required this.color, required this.onTap, }); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: MirrorTheme.surface, borderRadius: BorderRadius.circular(16), ), child: Row( children: [ Container( width: 48, height: 48, decoration: BoxDecoration( color: color.withValues(alpha: 0.15), borderRadius: BorderRadius.circular(12), ), child: Icon(icon, color: color), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, style: Theme.of(context).textTheme.labelLarge), const SizedBox(height: 2), Text( subtitle, style: Theme.of(context).textTheme.bodySmall, ), ], ), ), Icon(Icons.chevron_right, color: MirrorTheme.textMuted), ], ), ), ); } }