import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; 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'; class SessionSetupScreen extends StatefulWidget { const SessionSetupScreen({super.key}); @override State createState() => _SessionSetupScreenState(); } class _SessionSetupScreenState extends State { final _formKey = GlobalKey(); final _weaponController = TextEditingController(); int _shotsPerTarget = 5; int _distance = 25; List _availableWeapons = []; Weapon? _selectedWeapon; bool _isLoadingWeapons = true; @override void initState() { super.initState(); _loadWeapons(); } Future _loadWeapons() async { final repository = context.read(); final weapons = await repository.getWeapons(); if (mounted) { setState(() { _availableWeapons = weapons; _isLoadingWeapons = false; }); } } @override void dispose() { _weaponController.dispose(); super.dispose(); } void _startSession() { if (_formKey.currentState!.validate()) { final repository = context.read(); final sessionProvider = context.read(); final sessionId = repository.generateId(); sessionProvider.startSession( _selectedWeapon != null ? _selectedWeapon!.displayName : _weaponController.text, _shotsPerTarget, sessionId, weaponId: _selectedWeapon?.id, distance: _distance, ); Navigator.pushReplacement( context, MaterialPageRoute(builder: (_) => const CaptureScreen()), ); } } @override Widget build(BuildContext context) { 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( 'Choix de l\'arme', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), const SizedBox(height: 16), if (_availableWeapons.isNotEmpty) ...[ DropdownButtonFormField( value: _selectedWeapon, decoration: InputDecoration( labelText: 'Sélectionner une arme de l\'armurerie', prefixIcon: const Icon(Icons.shield), border: OutlineInputBorder( borderRadius: BorderRadius.circular(AppConstants.borderRadius), ), ), items: [ const DropdownMenuItem( value: null, child: Text('Nouvelle arme / Autre'), ), ..._availableWeapons.map((w) => DropdownMenuItem( value: w, child: Text(w.displayName), )), ], onChanged: (value) { setState(() { _selectedWeapon = value; if (value != null) { _weaponController.text = value.displayName; _shotsPerTarget = value.magazineCapacity; // Auto-set distance based on weapon type if needed _distance = (value.type == WeaponType.handgun) ? 25 : 50; } else { _weaponController.clear(); } }); }, ), const SizedBox(height: 16), const Center(child: Text('OU', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold))), const SizedBox(height: 16), ], // Weapon field (manual entry if no weapon selected) TextFormField( controller: _weaponController, enabled: _selectedWeapon == null, decoration: InputDecoration( labelText: 'Nom de l\'arme', hintText: 'ex: Glock 17, CZ Shadow 2...', prefixIcon: const Icon(Icons.edit), border: OutlineInputBorder( borderRadius: BorderRadius.circular(AppConstants.borderRadius), ), ), validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez renseigner votre arme'; } return null; }, ), 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, // (300-5)/5 = 59 divisions for 5m steps label: '${_distance}m', onChanged: (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: 30, divisions: 29, label: '$_shotsPerTarget', onChanged: (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: _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), ), ), ], ), ), ), ); } }