import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; import '../../services/auth_service.dart'; import '../../widgets/image_button.dart'; class CreatePasswordScreen extends StatefulWidget { final String? token; const CreatePasswordScreen({super.key, this.token}); @override State createState() => _CreatePasswordScreenState(); } class _CreatePasswordScreenState extends State { final _formKey = GlobalKey(); final _passwordCtrl = TextEditingController(); final _confirmCtrl = TextEditingController(); bool _checkingToken = true; bool _submitting = false; bool _tokenValid = false; String? _message; String get _token => (widget.token ?? '').trim(); @override void initState() { super.initState(); _checkToken(); } @override void dispose() { _passwordCtrl.dispose(); _confirmCtrl.dispose(); super.dispose(); } bool _isStrongPassword(String v) { if (v.length < 8) return false; final hasUpper = RegExp(r'[A-Z]').hasMatch(v); final hasDigit = RegExp(r'\d').hasMatch(v); return hasUpper && hasDigit; } String? _validatePassword(String? value) { final v = value ?? ''; if (v.isEmpty) return 'Veuillez saisir un mot de passe.'; if (!_isStrongPassword(v)) { return 'Minimum 8 caractères, avec au moins 1 majuscule et 1 chiffre.'; } return null; } String? _validateConfirmation(String? value) { final v = value ?? ''; if (v.isEmpty) return 'Veuillez confirmer le mot de passe.'; if (v != _passwordCtrl.text) return 'Les mots de passe ne correspondent pas.'; return null; } Future _checkToken() async { if (_token.isEmpty) { setState(() { _checkingToken = false; _tokenValid = false; }); return; } try { final ok = await AuthService.verifyCreatePasswordToken(_token); if (!mounted) return; setState(() { _checkingToken = false; _tokenValid = ok; }); } catch (e) { if (!mounted) return; setState(() { _checkingToken = false; _tokenValid = false; _message = e.toString().replaceAll('Exception: ', ''); }); } } Future _submit() async { if (_submitting || !_tokenValid) return; if (!(_formKey.currentState?.validate() ?? false)) return; setState(() { _submitting = true; _message = null; }); try { await AuthService.createPasswordWithToken( token: _token, password: _passwordCtrl.text, passwordConfirmation: _confirmCtrl.text, ); if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( 'Mot de passe créé avec succès. Vous pouvez vous connecter.', style: GoogleFonts.merienda(), ), ), ); context.go('/login'); } catch (e) { if (!mounted) return; setState(() { _submitting = false; _message = e.toString().replaceAll('Exception: ', ''); }); } } @override Widget build(BuildContext context) { return Scaffold( body: Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/paper2.png'), fit: BoxFit.cover, repeat: ImageRepeat.repeat, ), ), child: Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 560), child: Card( color: const Color(0xF4FFFFFF), margin: const EdgeInsets.all(24), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), child: Padding( padding: const EdgeInsets.all(24), child: _checkingToken ? const Center(child: CircularProgressIndicator()) : _tokenValid ? _buildForm() : _buildInvalidToken(), ), ), ), ), ), ); } Widget _buildForm() { return Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( 'Créer votre mot de passe', style: GoogleFonts.merienda(fontSize: 28, fontWeight: FontWeight.w700), textAlign: TextAlign.center, ), const SizedBox(height: 18), TextFormField( controller: _passwordCtrl, obscureText: true, validator: _validatePassword, decoration: const InputDecoration( labelText: 'Nouveau mot de passe', border: OutlineInputBorder(), ), ), const SizedBox(height: 14), TextFormField( controller: _confirmCtrl, obscureText: true, validator: _validateConfirmation, decoration: const InputDecoration( labelText: 'Confirmer le mot de passe', border: OutlineInputBorder(), ), ), const SizedBox(height: 10), Text( 'Le mot de passe doit contenir au moins 8 caractères, dont 1 majuscule et 1 chiffre.', style: GoogleFonts.merienda(fontSize: 12, color: Colors.black54), ), if (_message != null) ...[ const SizedBox(height: 12), Text( _message!, style: GoogleFonts.merienda(color: Colors.red.shade700), ), ], const SizedBox(height: 16), _submitting ? const Center(child: CircularProgressIndicator()) : ImageButton( bg: 'assets/images/bg_green.png', width: double.infinity, height: 44, text: 'Valider', textColor: const Color(0xFF2D6A4F), onPressed: _submit, ), ], ), ); } Widget _buildInvalidToken() { final msg = _message ?? 'Lien invalide ou expiré.'; return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( 'Création du mot de passe', style: GoogleFonts.merienda(fontSize: 28, fontWeight: FontWeight.w700), textAlign: TextAlign.center, ), const SizedBox(height: 20), Text( msg, style: GoogleFonts.merienda(fontSize: 16), textAlign: TextAlign.center, ), const SizedBox(height: 20), ImageButton( bg: 'assets/images/bg_green.png', width: double.infinity, height: 44, text: 'Retour à la connexion', textColor: const Color(0xFF2D6A4F), onPressed: () => context.go('/login'), ), ], ); } }