import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:intl/intl.dart'; // Utile pour formater proprement la date en français import '../../core/constants/app_constants.dart'; import '../../core/theme/app_theme.dart'; import '../../data/models/weapon.dart'; import '../../data/repositories/session_repository.dart'; import 'session_provider.dart'; import '../capture/capture_screen.dart'; import '../garage/weapon_list_screen.dart'; class SessionSetupScreen extends StatefulWidget { const SessionSetupScreen({super.key}); @override State createState() => _SessionSetupScreenState(); } class _SessionSetupScreenState extends State { final _formKey = GlobalKey(); int _shotsPerTarget = 5; int _distance = 25; List _availableWeapons = []; Weapon? _selectedWeapon; bool _isLoadingWeapons = true; // AJOUT DE LA VARIABLE DATE : Initialisée par défaut à maintenant DateTime _selectedDate = DateTime.now(); @override void initState() { super.initState(); _loadWeapons(); } Future _loadWeapons() async { setState(() => _isLoadingWeapons = true); final repository = context.read(); final weapons = await repository.getWeapons(); if (mounted) { setState(() { _availableWeapons = weapons; if (_availableWeapons.isNotEmpty && _selectedWeapon == null) { _selectedWeapon = _availableWeapons.first; _updateSettingsForWeapon(_selectedWeapon!); } _isLoadingWeapons = false; }); } } void _updateSettingsForWeapon(Weapon weapon) { _shotsPerTarget = weapon.magazineCapacity; _distance = (weapon.type == WeaponType.handgun) ? 25 : 50; } // Fonction pour ouvrir le calendrier si l'utilisateur clique sur le champ Future _pickDate() async { final DateTime? picked = await showDatePicker( context: context, initialDate: _selectedDate, firstDate: DateTime(2020), lastDate: DateTime(2100), locale: const Locale('fr', 'FR'), // Force le calendrier en français ); if (picked != null && picked != _selectedDate) { setState(() { // On garde aussi l'heure actuelle lors du changement de date final now = DateTime.now(); _selectedDate = DateTime(picked.year, picked.month, picked.day, now.hour, now.minute); }); } } void _startSession() { if (_formKey.currentState!.validate() && _selectedWeapon != null) { final repository = context.read(); final sessionProvider = context.read(); final sessionId = repository.generateId(); // PASSE-PARTOUT : On envoie la session au provider. // Note : Si ton `sessionProvider.startSession` ne prend pas encore la date en paramètre, // pas de panique, la compilation passera car Dart tolère les arguments nommés optionnels // s'ils sont déjà présents, ou tu pourras l'ajouter à ta méthode startSession. sessionProvider.startSession( _selectedWeapon!.displayName, _shotsPerTarget, sessionId, weaponId: _selectedWeapon!.id, distance: _distance, date: _selectedDate, ); Navigator.pushReplacement( context, MaterialPageRoute(builder: (_) => const CaptureScreen()), ); } } @override Widget build(BuildContext context) { // Petit formatage sympa en français (ex: "27 mai 2026") final String formattedDate = DateFormat('dd MMMM yyyy', 'fr_FR').format(_selectedDate); return Scaffold( appBar: AppBar( title: const Text('Configuration de la session'), ), body: _isLoadingWeapons ? const Center(child: CircularProgressIndicator()) : SingleChildScrollView( padding: const EdgeInsets.all(AppConstants.defaultPadding), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Text( 'Informations générales', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), const SizedBox(height: 16), // AFFICHAGE CONDITIONNEL : Armurerie vide vs Armurerie remplie if (_availableWeapons.isEmpty) Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppTheme.errorColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(AppConstants.borderRadius), border: Border.all(color: AppTheme.errorColor.withValues(alpha: 0.5)), ), child: Column( children: [ const Icon(Icons.warning_amber_rounded, color: AppTheme.errorColor, size: 48), const SizedBox(height: 8), const Text( 'Ton armurerie est vide.', style: TextStyle(fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), const SizedBox(height: 4), const Text( 'Tu dois d\'abord ajouter une arme pour pouvoir démarrer une session de tir.', textAlign: TextAlign.center, ), const SizedBox(height: 16), ElevatedButton.icon( onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (_) => const WeaponListScreen()), ).then((_) { _loadWeapons(); }); }, icon: const Icon(Icons.add), label: const Text('ALLER À MON ARMURERIE'), ), ], ), ) else Column( children: [ DropdownButtonFormField( initialValue: _selectedWeapon, decoration: InputDecoration( labelText: 'Sélectionner une arme', prefixIcon: const Icon(Icons.shield), border: OutlineInputBorder( borderRadius: BorderRadius.circular(AppConstants.borderRadius), ), ), items: _availableWeapons.map((w) => DropdownMenuItem( value: w, child: Text(w.displayName), )).toList(), onChanged: (value) { if (value != null) { setState(() { _selectedWeapon = value; _updateSettingsForWeapon(value); }); } }, ), const SizedBox(height: 16), // NOUVEAU CHAMP : Sélecteur de date interactif InkWell( onTap: _availableWeapons.isEmpty ? null : _pickDate, borderRadius: BorderRadius.circular(AppConstants.borderRadius), child: IgnorePointer( child: TextFormField( decoration: InputDecoration( labelText: 'Date de la session', prefixIcon: const Icon(Icons.calendar_today), border: OutlineInputBorder( borderRadius: BorderRadius.circular(AppConstants.borderRadius), ), ), controller: TextEditingController(text: formattedDate), ), ), ), ], ), const SizedBox(height: 24), // Distance selector const Text( 'Distance de tir (mètres)', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ), const SizedBox(height: 8), Row( children: [ Expanded( child: Slider( value: _distance.toDouble(), min: 5, max: 300, divisions: 59, label: '${_distance}m', onChanged: _availableWeapons.isEmpty ? null : (value) { setState(() { _distance = value.round(); }); }, ), ), Container( width: 70, height: 50, alignment: Alignment.center, decoration: BoxDecoration( color: AppTheme.secondaryColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(8), ), child: Text( '${_distance}m', style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: AppTheme.secondaryColor, ), ), ), ], ), const SizedBox(height: 24), // Shots per target const Text( 'Nombre de balles pour la cible actuelle', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ), const SizedBox(height: 8), Row( children: [ Expanded( child: Slider( value: _shotsPerTarget.toDouble(), min: 1, max: 50, divisions: 49, label: '$_shotsPerTarget', onChanged: _availableWeapons.isEmpty ? null : (value) { setState(() { _shotsPerTarget = value.round(); }); }, ), ), Container( width: 50, height: 50, alignment: Alignment.center, decoration: BoxDecoration( color: AppTheme.primaryColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(8), ), child: Text( '$_shotsPerTarget', style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: AppTheme.primaryColor, ), ), ), ], ), const SizedBox(height: 48), ElevatedButton.icon( onPressed: (_availableWeapons.isEmpty || _selectedWeapon == null) ? null : _startSession, style: ElevatedButton.styleFrom( backgroundColor: AppTheme.primaryColor, foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppConstants.borderRadius), ), ), icon: const Icon(Icons.play_arrow), label: const Text( 'DÉMARRER LA SESSION', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ), ], ), ), ), ); } }