import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../providers/energy_setup_provider.dart'; import '../../providers/installer_mode_provider.dart'; import '../../services/nymea_service.dart'; import '../../theme/etm_theme.dart'; import '../../widgets/role_card.dart'; import 'role_config_flow.dart'; /// Écran "Rôles & appareils" — configuration des rôles EMS. /// Accessible uniquement en mode installateur. class EnergySetupScreen extends StatelessWidget { const EnergySetupScreen({super.key}); @override Widget build(BuildContext context) { final installer = context.watch(); return Scaffold( backgroundColor: const Color(0xFFF0F2F5), appBar: AppBar( title: const Text('Rôles & appareils'), backgroundColor: Colors.white, foregroundColor: const Color(0xFF1A1A2E), elevation: 0, actions: [ IconButton( icon: const Icon(Icons.help_outline_rounded), tooltip: 'Aide', onPressed: () => _showHelp(context), ), ], ), body: installer.isUnlocked ? _SetupBody() : _LockedOverlay(), ); } void _showHelp(BuildContext context) { showModalBottomSheet( context: context, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(20)), ), builder: (_) => Padding( padding: const EdgeInsets.all(24), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: const [ Text('Rôles & appareils', style: TextStyle(fontSize: 17, fontWeight: FontWeight.bold)), SizedBox(height: 12), Text( 'Assignez chaque appareil physique à son rôle dans ' 'le système de gestion d\'énergie.\n\n' 'Le gestionnaire d\'énergie utilise ces assignations pour ' 'optimiser la consommation et maximiser l\'autoconsommation.', style: TextStyle(fontSize: 14), ), ], ), ), ); } } class _LockedOverlay extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.lock_rounded, size: 48, color: Colors.grey.shade400), const SizedBox(height: 16), const Text( 'Mode installateur requis', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), const Text( 'Activez le mode installateur depuis le menu\npour accéder à cet écran.', textAlign: TextAlign.center, style: TextStyle(color: Color(0xFF6B7280)), ), ], ), ); } } class _SetupBody extends StatelessWidget { @override Widget build(BuildContext context) { final setup = context.watch(); final service = context.read(); return ListView( padding: const EdgeInsets.all(16), children: [ // Bannière d'info Container( padding: const EdgeInsets.all(12), margin: const EdgeInsets.only(bottom: 16), decoration: BoxDecoration( color: ETMTheme.accentColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(12), border: Border.all( color: ETMTheme.accentColor.withValues(alpha: 0.3)), ), child: Row( children: [ const Icon(Icons.info_outline_rounded, color: ETMTheme.accentColor, size: 18), const SizedBox(width: 10), Expanded( child: Text( '${EmsRole.values.where((r) => setup.isConfigured(r)).length} / ' '${EmsRole.values.length} rôles configurés', style: const TextStyle( fontSize: 13, color: ETMTheme.accentColor, fontWeight: FontWeight.w500, ), ), ), ], ), ), ...EmsRole.values.map((role) => RoleCard( role: role, assignment: setup.assignmentFor(role), isReachable: true, onConfigure: () => _openConfigFlow(context, role, null), onToggle: setup.isConfigured(role) ? () => setup.setEnabled( role, !(setup.assignmentFor(role)?.enabled ?? false), ) : null, onEdit: setup.isConfigured(role) ? () => _openConfigFlow( context, role, setup.assignmentFor(role), ) : null, onTest: setup.isConfigured(role) ? () => setup.testConnection(role, service) : null, )), ], ); } Future _openConfigFlow( BuildContext context, EmsRole role, RoleAssignment? existing) async { await showModalBottomSheet( context: context, isScrollControlled: true, useSafeArea: true, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(20)), ), builder: (_) => RoleConfigFlow(role: role, existing: existing), ); } }