import 'package:flutter/material.dart'; import 'dart:async'; import '../services/odoo_service.dart'; import '../services/config.dart'; import '../theme/app_theme.dart'; class ForgotPasswordScreen extends StatefulWidget { const ForgotPasswordScreen({super.key}); @override State createState() => _ForgotPasswordScreenState(); } class _ForgotPasswordScreenState extends State { final _phoneOrEmailController = TextEditingController(); final _otpController = TextEditingController(); final _passwordController = TextEditingController(); final _confirmPasswordController = TextEditingController(); bool _isLoading = false; bool _sendingOtp = false; bool _otpSent = false; int _countdown = 0; Timer? _timer; String? _targetEmail; // The email returned by Odoo where OTP was sent @override void dispose() { _phoneOrEmailController.dispose(); _otpController.dispose(); _passwordController.dispose(); _confirmPasswordController.dispose(); _timer?.cancel(); super.dispose(); } void _sendResetCode() async { final phoneOrEmail = _phoneOrEmailController.text.trim(); if (phoneOrEmail.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please enter your phone number or email.')), ); return; } setState(() => _sendingOtp = true); try { final service = OdooService(); service.connect(AppConfig.odooUrl); final response = await service.sendOtp( phoneOrEmail: phoneOrEmail, type: 'reset_password', ); if (response != null && response['status'] == 'success') { setState(() { _otpSent = true; _countdown = 60; _targetEmail = response['email']; }); _startTimer(); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(response['message'] ?? 'Verification code sent!')), ); } } else { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(response?['message'] ?? 'Failed to send reset code.')), ); } } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error: $e')), ); } } finally { if (mounted) { setState(() => _sendingOtp = false); } } } void _startTimer() { _timer?.cancel(); _timer = Timer.periodic(const Duration(seconds: 1), (timer) { if (_countdown == 0) { timer.cancel(); } else { setState(() { _countdown--; }); } }); } void _resetPassword() async { final phoneOrEmail = _phoneOrEmailController.text.trim(); final otp = _otpController.text.trim(); final password = _passwordController.text; final confirmPassword = _confirmPasswordController.text; if (phoneOrEmail.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please enter your phone number or email.')), ); return; } if (otp.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please enter the verification code (OTP).')), ); return; } if (password.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please enter a new password.')), ); return; } if (password != confirmPassword) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Passwords do not match.')), ); return; } setState(() => _isLoading = true); try { final service = OdooService(); service.connect(AppConfig.odooUrl); final response = await service.resetPassword( phoneOrEmail: phoneOrEmail, otp: otp, password: password, ); if (response != null && response['status'] == 'success') { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(response['message'] ?? 'Password reset successfully!')), ); Navigator.of(context).pop(); } } else { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(response?['message'] ?? 'Reset failed.')), ); } } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error: $e')), ); } } finally { if (mounted) { setState(() => _isLoading = false); } } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Reset Password'), ), body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 32.0, vertical: 24.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( 'Forgot Password?', style: Theme.of(context).textTheme.headlineMedium?.copyWith( color: AppTheme.onSurface, fontSize: 28, ), ), const SizedBox(height: 8), Text( 'Enter your phone number or email address. We will send a verification code to your registered email to reset your password.', style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: AppTheme.onSurfaceVariant, ), ), const SizedBox(height: 36), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( child: TextField( controller: _phoneOrEmailController, keyboardType: TextInputType.text, decoration: const InputDecoration( labelText: 'Phone Number or Email', hintText: 'e.g. 08123456789 or name@domain.com', ), enabled: !_otpSent, ), ), if (!_otpSent) ...[ const SizedBox(width: 12), _sendingOtp ? const Padding( padding: EdgeInsets.only(bottom: 8.0), child: SizedBox( width: 32, height: 32, child: CircularProgressIndicator(strokeWidth: 2.5), ), ) : Padding( padding: const EdgeInsets.only(bottom: 4.0), child: ElevatedButton( onPressed: _sendResetCode, style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), minimumSize: Size.zero, ), child: const Text( 'Send OTP', style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), ), ), ), ], ], ), if (_otpSent) ...[ const SizedBox(height: 20), if (_targetEmail != null) ...[ Text( 'OTP has been sent to your registered email address.', style: TextStyle( color: AppTheme.secondary.withOpacity(0.8), fontWeight: FontWeight.w500, fontSize: 13, ), ), const SizedBox(height: 12), ], TextField( controller: _otpController, keyboardType: TextInputType.number, decoration: const InputDecoration( labelText: 'Verification Code (OTP)', hintText: 'Enter 6-digit code', prefixIcon: Icon(Icons.security), ), ), const SizedBox(height: 20), TextField( controller: _passwordController, decoration: const InputDecoration( labelText: 'New Password', ), obscureText: true, ), const SizedBox(height: 20), TextField( controller: _confirmPasswordController, decoration: const InputDecoration( labelText: 'Confirm New Password', ), obscureText: true, ), const SizedBox(height: 12), Align( alignment: Alignment.centerLeft, child: TextButton( onPressed: _sendingOtp ? null : _sendResetCode, child: Text( _countdown > 0 ? 'Resend code in ${_countdown}s' : 'Resend Verification Code', style: const TextStyle(color: AppTheme.secondary), ), ), ), const SizedBox(height: 24), SizedBox( height: 56, child: _isLoading ? const Center(child: CircularProgressIndicator()) : ElevatedButton( onPressed: _resetPassword, child: const Text( 'Reset Password', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ), ], ], ), ), ), ); } }