import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; import 'package:google_fonts/google_fonts.dart'; import 'dart:math' as math; import 'dart:io'; // Pour FileImage si _pickPhoto utilise un File import '../../models/am_registration_data.dart'; import '../../widgets/custom_app_text_field.dart'; import '../../widgets/app_custom_checkbox.dart'; // Import de la checkbox import '../../widgets/hover_relief_widget.dart'; // Import du HoverReliefWidget import '../../models/card_assets.dart'; import '../../utils/data_generator.dart'; class AmRegisterStep2Screen extends StatefulWidget { const AmRegisterStep2Screen({super.key}); @override State createState() => _AmRegisterStep2ScreenState(); } class _AmRegisterStep2ScreenState extends State { final _formKey = GlobalKey(); final _dateOfBirthController = TextEditingController(); // final _placeOfBirthController = TextEditingController(); // Remplacé final _birthCityController = TextEditingController(); // Nouveau final _birthCountryController = TextEditingController(); // Nouveau final _nirController = TextEditingController(); final _agrementController = TextEditingController(); final _capacityController = TextEditingController(); DateTime? _selectedDate; String? _photoPathFramework; // Pour stocker le chemin de la photo (Asset ou File path) File? _photoFile; // Pour stocker le fichier image si sélectionné localement bool _photoConsent = false; @override void initState() { super.initState(); final data = Provider.of(context, listen: false); _selectedDate = data.dateOfBirth; _dateOfBirthController.text = data.dateOfBirth != null ? DateFormat('dd/MM/yyyy').format(data.dateOfBirth!) : ''; _birthCityController.text = data.birthCity; _birthCountryController.text = data.birthCountry; _nirController.text = data.nir; _agrementController.text = data.agrementNumber; _capacityController.text = data.capacity?.toString() ?? ''; // Générer des données de test si les champs sont vides if (data.dateOfBirth == null && data.nir.isEmpty) { _selectedDate = DateTime(1985, 3, 15); _dateOfBirthController.text = DateFormat('dd/MM/yyyy').format(_selectedDate!); _birthCityController.text = DataGenerator.city(); _birthCountryController.text = 'France'; _nirController.text = '${DataGenerator.randomIntInRange(1, 3)}${DataGenerator.randomIntInRange(80, 96)}${DataGenerator.randomIntInRange(1, 13).toString().padLeft(2, '0')}${DataGenerator.randomIntInRange(1, 100).toString().padLeft(2, '0')}${DataGenerator.randomIntInRange(100, 1000).toString().padLeft(3, '0')}${DataGenerator.randomIntInRange(100, 1000).toString().padLeft(3, '0')}${DataGenerator.randomIntInRange(10, 100).toString().padLeft(2, '0')}'; _agrementController.text = 'AM${DataGenerator.randomIntInRange(10000, 100000)}'; _capacityController.text = DataGenerator.randomIntInRange(1, 5).toString(); _photoPathFramework = 'assets/images/icon_assmat.png'; _photoConsent = true; } // Gérer la photo existante (pourrait être un path d'asset ou un path de fichier) if (data.photoPath != null) { if (data.photoPath!.startsWith('assets/')) { _photoPathFramework = data.photoPath; _photoFile = null; } else { _photoFile = File(data.photoPath!); _photoPathFramework = data.photoPath; // ou _photoFile.path } } _photoConsent = data.photoConsent; } @override void dispose() { _dateOfBirthController.dispose(); _birthCityController.dispose(); _birthCountryController.dispose(); _nirController.dispose(); _agrementController.dispose(); _capacityController.dispose(); super.dispose(); } Future _selectDate(BuildContext context) async { final DateTime? picked = await showDatePicker( context: context, initialDate: _selectedDate ?? DateTime.now().subtract(const Duration(days: 365 * 25)), // Default à 25 ans si null firstDate: DateTime(1920, 1), lastDate: DateTime.now().subtract(const Duration(days: 365 * 18)), // Assurer un âge minimum de 18 ans locale: const Locale('fr', 'FR'), ); if (picked != null && picked != _selectedDate) { setState(() { _selectedDate = picked; _dateOfBirthController.text = DateFormat('dd/MM/yyyy').format(picked); }); } } Future _pickPhoto() async { // TODO: Remplacer par la vraie logique ImagePicker // final imagePicker = ImagePicker(); // final pickedFile = await imagePicker.pickImage(source: ImageSource.gallery); // if (pickedFile != null) { // setState(() { // _photoFile = File(pickedFile.path); // _photoPathFramework = pickedFile.path; // pour la sauvegarde // }); // } else { // // Simuler la sélection d'un asset pour test si aucun fichier n'est choisi setState(() { _photoPathFramework = 'assets/images/icon_assmat.png'; // Simule une photo asset _photoFile = null; // Assurez-vous que _photoFile est null si c'est un asset }); // } print("Photo sélectionnée: $_photoPathFramework"); } void _submitForm() { if (_formKey.currentState!.validate()) { if (_photoPathFramework != null && !_photoConsent) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Veuillez accepter le consentement photo pour continuer.')), ); return; } Provider.of(context, listen: false) .updateProfessionalInfo( photoPath: _photoPathFramework, // Sauvegarder le chemin (asset ou fichier) photoConsent: _photoConsent, dateOfBirth: _selectedDate, birthCity: _birthCityController.text, birthCountry: _birthCountryController.text, nir: _nirController.text, agrementNumber: _agrementController.text, capacity: int.tryParse(_capacityController.text) ); context.go('/am-register-step3'); } } @override Widget build(BuildContext context) { final screenSize = MediaQuery.of(context).size; const cardColor = CardColorHorizontal.green; // Couleur de la carte final Color baseCardColorForShadow = Colors.green.shade300; final Color initialPhotoShadow = baseCardColorForShadow.withAlpha(90); final Color hoverPhotoShadow = baseCardColorForShadow.withAlpha(130); ImageProvider? currentImageProvider; if (_photoFile != null) { currentImageProvider = FileImage(_photoFile!); } else if (_photoPathFramework != null && _photoPathFramework!.startsWith('assets/')) { currentImageProvider = AssetImage(_photoPathFramework!); } return Scaffold( body: Stack( children: [ Positioned.fill( child: Image.asset('assets/images/paper2.png', fit: BoxFit.cover, repeat: ImageRepeat.repeat), ), Center( child: SingleChildScrollView( padding: const EdgeInsets.symmetric(vertical: 40.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Étape 2/4', style: GoogleFonts.merienda(fontSize: 16, color: Colors.black54)), const SizedBox(height: 10), Text( 'Vos informations professionnelles', style: GoogleFonts.merienda( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.black87, ), textAlign: TextAlign.center, ), const SizedBox(height: 30), Container( width: screenSize.width * 0.6, padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 50), constraints: const BoxConstraints(minHeight: 650), decoration: BoxDecoration( image: DecorationImage(image: AssetImage(cardColor.path), fit: BoxFit.fill), ), child: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Colonne Gauche: Photo et Checkbox SizedBox( width: 300, // Largeur fixe pour la colonne photo (200 * 1.5) child: Column( crossAxisAlignment: CrossAxisAlignment.center, // Centrer les éléments horizontalement children: [ HoverReliefWidget( onPressed: _pickPhoto, borderRadius: BorderRadius.circular(10.0), initialShadowColor: initialPhotoShadow, hoverShadowColor: hoverPhotoShadow, child: SizedBox( height: 270, // (180 * 1.5) width: 270, // (180 * 1.5) child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), image: currentImageProvider != null ? DecorationImage(image: currentImageProvider, fit: BoxFit.cover) : null, ), child: currentImageProvider == null ? Image.asset('assets/images/photo.png', fit: BoxFit.contain) : null, ), ), ), const SizedBox(height: 10), // Espace réduit AppCustomCheckbox( label: 'J\'accepte l\'utilisation\nde ma photo.', value: _photoConsent, onChanged: (val) => setState(() => _photoConsent = val ?? false), ), ], ), ), const SizedBox(width: 30), // Augmenter l'espace entre les colonnes // Colonne Droite: Champs de naissance Expanded( child: Column( children: [ CustomAppTextField( controller: _birthCityController, labelText: 'Ville de naissance', hintText: 'Votre ville de naissance', fieldWidth: double.infinity, validator: (v) => v!.isEmpty ? 'Ville requise' : null, ), const SizedBox(height: 32), CustomAppTextField( controller: _birthCountryController, labelText: 'Pays de naissance', hintText: 'Votre pays de naissance', fieldWidth: double.infinity, validator: (v) => v!.isEmpty ? 'Pays requis' : null, ), const SizedBox(height: 32), CustomAppTextField( controller: _dateOfBirthController, labelText: 'Date de naissance', hintText: 'JJ/MM/AAAA', readOnly: true, onTap: () => _selectDate(context), suffixIcon: Icons.calendar_today, // Assurez-vous que CustomAppTextField gère suffixIcon fieldWidth: double.infinity, validator: (v) => _selectedDate == null ? 'Date requise' : null, ), ], ), ), ], ), const SizedBox(height: 32), CustomAppTextField( controller: _nirController, labelText: 'N° Sécurité Sociale (NIR)', hintText: 'Votre NIR à 13 chiffres', keyboardType: TextInputType.number, fieldWidth: double.infinity, validator: (v) { // Validation plus précise du NIR if (v == null || v.isEmpty) return 'NIR requis'; if (v.length != 13) return 'Le NIR doit contenir 13 chiffres'; if (!RegExp(r'^[1-3]').hasMatch(v[0])) return 'Le NIR doit commencer par 1, 2 ou 3'; // D'autres validations plus complexes (clé de contrôle) peuvent être ajoutées return null; }, ), const SizedBox(height: 32), Row( children: [ Expanded( child: CustomAppTextField( controller: _agrementController, labelText: 'N° d\'agrément', hintText: 'Votre numéro d\'agrément', fieldWidth: double.infinity, validator: (v) => v!.isEmpty ? 'Agrément requis' : null, ), ), const SizedBox(width: 20), Expanded( child: CustomAppTextField( controller: _capacityController, labelText: 'Capacité d\'accueil', hintText: 'Ex: 3', keyboardType: TextInputType.number, fieldWidth: double.infinity, validator: (v) { if (v == null || v.isEmpty) return 'Capacité requise'; final n = int.tryParse(v); if (n == null || n <= 0) return 'Nombre invalide'; return null; }, ), ), ], ), ], ), ), ), ], ), ), ), // Chevron Gauche (Retour) Positioned( top: screenSize.height / 2 - 20, left: 40, child: IconButton( icon: Transform(alignment: Alignment.center, transform: Matrix4.rotationY(math.pi), child: Image.asset('assets/images/chevron_right.png', height: 40)), onPressed: () { if (context.canPop()) { context.pop(); } else { context.go('/am-register-step1'); } }, tooltip: 'Précédent', ), ), // Chevron Droit (Suivant) Positioned( top: screenSize.height / 2 - 20, right: 40, child: IconButton( icon: Image.asset('assets/images/chevron_right.png', height: 40), onPressed: _submitForm, tooltip: 'Suivant', ), ), ], ), ); } }