@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
 
		
	
		
			
				import  ' package:flutter/rendering.dart ' ;  
		
	
		
			
				import  ' package:flutter/services.dart ' ;  
		
	
		
			
				import  ' package:hmg_patient_app_new/core/utils/size_utils.dart ' ;  
		
	
		
			
				import  ' package:hmg_patient_app_new/extensions/widget_extensions.dart ' ;  
		
	
		
			
				import  ' package:hmg_patient_app_new/theme/colors.dart ' ;  
		
	
		
			
				import  ' package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart ' ;  
		
	
		
			
				
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -50,12 +51,12 @@ class OTPWidget extends StatefulWidget {
 
		
	
		
			
				  final  TextInputType  keyboardType ; 
 
		
	
		
			
				  final  EdgeInsets  pinBoxOuterPadding ; 
 
		
	
		
			
				
 
		
	
		
			
				  OTPWidget ( { 
 
		
	
		
			
				  const  OTPWidget ( { 
 
		
	
		
			
				    Key ?  key , 
 
		
	
		
			
				    this . maxLength  =  4 , 
 
		
	
		
			
				    this . controller , 
 
		
	
		
			
				    this . pinBoxWidth  =  70.0 , 
 
		
	
		
			
				    this . pinBoxHeight  =  10 0.0, 
 
		
	
		
			
				    this . pinBoxHeight  =  7 0.0, 
 
		
	
		
			
				    this . pinTextStyle , 
 
		
	
		
			
				    this . onDone , 
 
		
	
		
			
				    this . defaultBorderColor  =  Colors . black , 
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -127,7 +128,9 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
 
		
	
		
			
				    _highlightAnimationController  =  AnimationController ( vsync:  this ) ; 
 
		
	
		
			
				    _initTextController ( ) ; 
 
		
	
		
			
				    _calculateStrList ( ) ; 
 
		
	
		
			
				    if  ( widget . controller  ! =  null )  { 
 
		
	
		
			
				      widget . controller ! . addListener ( _controllerListener ) ; 
 
		
	
		
			
				    } 
 
		
	
		
			
				    focusNode . addListener ( _focusListener ) ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -190,7 +193,9 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
 
		
	
		
			
				      focusNode . removeListener ( _focusListener ) ; 
 
		
	
		
			
				    } 
 
		
	
		
			
				    _highlightAnimationController . dispose ( ) ; 
 
		
	
		
			
				    widget . controller ? . removeListener ( _controllerListener ) ; 
 
		
	
		
			
				    if  ( widget . controller  ! =  null )  { 
 
		
	
		
			
				      widget . controller ! . removeListener ( _controllerListener ) ; 
 
		
	
		
			
				    } 
 
		
	
		
			
				
 
		
	
		
			
				    super . dispose ( ) ; 
 
		
	
		
			
				  } 
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -231,7 +236,7 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
 
		
	
		
			
				        width:  0.0 , 
 
		
	
		
			
				      ) , 
 
		
	
		
			
				    ) ; 
 
		
	
		
			
				    return  SizedBox ( 
 
		
	
		
			
				    return  Container ( 
 
		
	
		
			
				      width:  _width , 
 
		
	
		
			
				      height:  widget . pinBoxHeight , 
 
		
	
		
			
				      child:  TextField ( 
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -241,8 +246,6 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
 
		
	
		
			
				        controller:  widget . controller , 
 
		
	
		
			
				        keyboardType:  widget . keyboardType , 
 
		
	
		
			
				        inputFormatters:  widget . keyboardType  = =  TextInputType . number  ?  < TextInputFormatter > [ FilteringTextInputFormatter . digitsOnly ]  :  null , 
 
		
	
		
			
				        / /  Enable  SMS  autofill 
 
		
	
		
			
				        autofillHints:  const  [ AutofillHints . oneTimeCode ] , 
 
		
	
		
			
				        style:  TextStyle ( 
 
		
	
		
			
				          height:  0.1 , 
 
		
	
		
			
				          color:  Colors . transparent , 
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -301,33 +304,28 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
 
		
	
		
			
				      return  _buildPinCode ( i ,  context ) ; 
 
		
	
		
			
				    } ) ; 
 
		
	
		
			
				    return  Row ( 
 
		
	
		
			
				      children:  pinCodes , 
 
		
	
		
			
				      mainAxisSize:  MainAxisSize . min , 
 
		
	
		
			
				      mainAxisAlignment:  MainAxisAlignment . spaceBetween , 
 
		
	
		
			
				      children:  pinCodes , 
 
		
	
		
			
				    ) ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
		
			
				  Widget  _buildPinCode ( int  i ,  BuildContext  context )  { 
 
		
	
		
			
				    Color  borderColor ; 
 
		
	
		
			
				    Color  pinBoxColor ; 
 
		
	
		
			
				
 
		
	
		
			
				    / /  Determine  if  OTP  is  complete 
 
		
	
		
			
				    bool  isComplete  =  text . length  = =  widget . maxLength ; 
 
		
	
		
			
				    Color  pinBoxColor  =  widget . pinBoxColor ; 
 
		
	
		
			
				
 
		
	
		
			
				    if  ( widget . hasError )  { 
 
		
	
		
			
				      borderColor  =  widget . errorBorderColor ; 
 
		
	
		
			
				      pinBoxColor  =  widget . pinBoxColor ; 
 
		
	
		
			
				    }  else  if  ( isComplete )  { 
 
		
	
		
			
				      borderColor  =  Colors . transparent ; 
 
		
	
		
			
				      pinBoxColor  =  AppColors . successColor ; 
 
		
	
		
			
				      pinBoxColor  =  widget . errorBorderColor ; 
 
		
	
		
			
				    }  else  if  ( i  <  text . length )  { 
 
		
	
		
			
				      borderColor  =  Colors . transparent ; 
 
		
	
		
			
				      pinBoxColor  =  AppColors . blackBgColor ; 
 
		
	
		
			
				      pinBoxColor  =  AppColors . blackBgColor ;  / /  Custom  color  for  filled  boxes 
 
		
	
		
			
				    }  else  { 
 
		
	
		
			
				      borderColor  =  Colors . transparent ; 
 
		
	
		
			
				      pinBoxColor  =  widget . pinBoxColor ; 
 
		
	
		
			
				    } 
 
		
	
		
			
				
 
		
	
		
			
				    / /  Change  color  to  success  when  all  fields  are  complete 
 
		
	
		
			
				    if  ( text . length  = =  widget . maxLength )  { 
 
		
	
		
			
				      pinBoxColor  =  AppColors . successColor ; 
 
		
	
		
			
				    } 
 
		
	
		
			
				
 
		
	
		
			
				    EdgeInsets  insets ; 
 
		
	
		
			
				    if  ( i  = =  0 )  { 
 
		
	
		
			
				      insets  =  EdgeInsets . only ( 
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -346,22 +344,21 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
 
		
	
		
			
				    }  else  { 
 
		
	
		
			
				      insets  =  widget . pinBoxOuterPadding ; 
 
		
	
		
			
				    } 
 
		
	
		
			
				    return  Container ( 
 
		
	
		
			
				
 
		
	
		
			
				    return  AnimatedContainer ( 
 
		
	
		
			
				      duration:  const  Duration ( milliseconds:  200 ) , 
 
		
	
		
			
				      curve:  Curves . easeInOut , 
 
		
	
		
			
				      key:  ValueKey < String > ( " container $ i " ) , 
 
		
	
		
			
				      alignment:  Alignment . center , 
 
		
	
		
			
				      padding:  EdgeInsets . symmetric ( vertical:  4.0 ,  horizontal:  1.0 ) , 
 
		
	
		
			
				      margin:  insets , 
 
		
	
		
			
				      decoration:  BoxDecoration ( 
 
		
	
		
			
				        border:  Border . all ( 
 
		
	
		
			
				          color:  borderColor , 
 
		
	
		
			
				          width:  widget . pinBoxBorderWidth , 
 
		
	
		
			
				        ) , 
 
		
	
		
			
				      child:  _animatedTextBox ( strList [ i ] ,  i ) , 
 
		
	
		
			
				      decoration:  RoundedRectangleBorder ( ) . toSmoothCornerDecoration ( 
 
		
	
		
			
				        color:  pinBoxColor , 
 
		
	
		
			
				        borderRadius:  BorderRadius. circular (  widget. pinBoxRadius ) , 
 
		
	
		
			
				        borderRadius:  widget . pinBoxRadius , 
 
		
	
		
			
				      ) , 
 
		
	
		
			
				      width:  widget . pinBoxWidth , 
 
		
	
		
			
				      height:  widget . pinBoxHeight , 
 
		
	
		
			
				      child:  _animatedTextBox ( strList [ i ] ,  i ) , 
 
		
	
		
			
				    ) ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -407,10 +404,12 @@ class OTPVerificationScreen extends StatefulWidget {
 
		
	
		
			
				
 
		
	
		
			
				class  _OTPVerificationScreenState  extends  State < OTPVerificationScreen >  {  
		
	
		
			
				  final  int  _otpLength  =  4 ; 
 
		
	
		
			
				  late  TextEditingController  _otpController ; 
 
		
	
		
			
				  late  final  TextEditingController  _otpController ; 
 
		
	
		
			
				
 
		
	
		
			
				  Timer ?  _resendTimer ; 
 
		
	
		
			
				  int  _resendTime  =  60 ; 
 
		
	
		
			
				  int  _resendTime  =  120 ; 
 
		
	
		
			
				  bool  _isOtpComplete  =  false ; 
 
		
	
		
			
				  bool  _isVerifying  =  false ;  / /  Flag  to  prevent  multiple  verification  calls 
 
		
	
		
			
				
 
		
	
		
			
				  @ override 
 
		
	
		
			
				  void  initState ( )  { 
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -437,29 +436,27 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
		
			
				  void  _onOtpChanged ( String  value )  { 
 
		
	
		
			
				    / /  Handle  clipboard  paste  or  programmatic  input 
 
		
	
		
			
				    if  ( value . length  >  1 )  { 
 
		
	
		
			
				      String ?  otp  =  _extractOtpFromText ( value ) ; 
 
		
	
		
			
				      if  ( otp  ! =  null )  { 
 
		
	
		
			
				        autoFillOtp ( otp ) ; 
 
		
	
		
			
				        return ; 
 
		
	
		
			
				      } 
 
		
	
		
			
				    } 
 
		
	
		
			
				    setState ( ( )  { 
 
		
	
		
			
				      _isOtpComplete  =  value . length  = =  _otpLength ; 
 
		
	
		
			
				    } ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    / /  The  OTPWidget  will  automatically  call  onDone  when  complete 
 
		
	
		
			
				    / /  This  method  can  be  used  for  any  additional  logic  on  text  change 
 
		
	
		
			
				    if  ( _isOtpComplete  & &  ! _isVerifying )  { 
 
		
	
		
			
				      _isVerifying  =  true ; 
 
		
	
		
			
				      _verifyOtp ( value ) ; 
 
		
	
		
			
				    }  else  if  ( ! _isOtpComplete )  { 
 
		
	
		
			
				      / /  Reset  the  flag  when  OTP  is  incomplete  ( user  is  editing ) 
 
		
	
		
			
				      _isVerifying  =  false ; 
 
		
	
		
			
				    } 
 
		
	
		
			
				
 
		
	
		
			
				  void  _onOtpCompleted ( String  otp )  { 
 
		
	
		
			
				    debugPrint ( ' OTP Completed:  $ otp ' ) ; 
 
		
	
		
			
				    widget . checkActivationCode ( int . parse ( otp ) ) ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
		
			
				  void  _resendOtp ( )  { 
 
		
	
		
			
				    if  ( _resendTime  = =  0 )  { 
 
		
	
		
			
				      setState ( ( )  = >  _resendTime  =  60 ) ; 
 
		
	
		
			
				      setState ( ( )  { 
 
		
	
		
			
				        _resendTime  =  120 ; 
 
		
	
		
			
				        _isVerifying  =  false ;  / /  Reset  verification  flag 
 
		
	
		
			
				      } ) ; 
 
		
	
		
			
				      _startResendTimer ( ) ; 
 
		
	
		
			
				      autoFillOtp ( " 1234 " ) ; 
 
		
	
		
			
				      / /  autoFillOtp ( " 1234 " ) ; 
 
		
	
		
			
				      widget . onResendOTPPressed ( widget . phoneNumber ) ; 
 
		
	
		
			
				    } 
 
		
	
		
			
				  } 
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -469,68 +466,6 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
 
		
	
		
			
				    return  phone . length  >  4  ?  ' 05xxxxxx ${ phone . substring ( phone . length  -  2 ) } '  :  phone ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
		
			
				  / / /  Extract  OTP  from  text  using  multiple  patterns 
 
		
	
		
			
				  String ?  _extractOtpFromText ( String  text )  { 
 
		
	
		
			
				    / /  Pattern  1 :  Find  4 - 6  consecutive  digits 
 
		
	
		
			
				    RegExp  digitPattern  =  RegExp ( r'\b\d{4,6}\b' ) ; 
 
		
	
		
			
				    Match ?  match  =  digitPattern . firstMatch ( text ) ; 
 
		
	
		
			
				    
 
		
	
		
			
				    if  ( match  ! =  null )  { 
 
		
	
		
			
				      String  digits  =  match . group ( 0 ) ! ; 
 
		
	
		
			
				      if  ( digits . length  > =  _otpLength )  { 
 
		
	
		
			
				        return  digits . substring ( 0 ,  _otpLength ) ; 
 
		
	
		
			
				      } 
 
		
	
		
			
				    } 
 
		
	
		
			
				    
 
		
	
		
			
				    / /  Pattern  2 :  Find  digits  separated  by  spaces  or  special  characters 
 
		
	
		
			
				    String  cleanedText  =  text . replaceAll ( RegExp ( r'[^\d]' ) ,  ' ' ) ; 
 
		
	
		
			
				    if  ( cleanedText . length  > =  _otpLength )  { 
 
		
	
		
			
				      return  cleanedText . substring ( 0 ,  _otpLength ) ; 
 
		
	
		
			
				    } 
 
		
	
		
			
				    
 
		
	
		
			
				    return  null ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
		
			
				  / / /  Paste  OTP  from  clipboard 
 
		
	
		
			
				  Future < void >  _pasteFromClipboard ( )  async  { 
 
		
	
		
			
				    try  { 
 
		
	
		
			
				      ClipboardData ?  data  =  await  Clipboard . getData ( Clipboard . kTextPlain ) ; 
 
		
	
		
			
				      if  ( data  ! =  null  & &  data . text  ! =  null )  { 
 
		
	
		
			
				        String  clipboardText  =  data . text ! ; 
 
		
	
		
			
				        String ?  otp  =  _extractOtpFromText ( clipboardText ) ; 
 
		
	
		
			
				        
 
		
	
		
			
				        if  ( otp  ! =  null )  { 
 
		
	
		
			
				          autoFillOtp ( otp ) ; 
 
		
	
		
			
				          
 
		
	
		
			
				          / /  Show  feedback  to  user 
 
		
	
		
			
				          ScaffoldMessenger . of ( context ) . showSnackBar ( 
 
		
	
		
			
				            SnackBar ( 
 
		
	
		
			
				              content:  Text ( ' OTP pasted:  $ otp ' ) , 
 
		
	
		
			
				              duration:  const  Duration ( seconds:  2 ) , 
 
		
	
		
			
				              backgroundColor:  AppColors . successColor , 
 
		
	
		
			
				            ) , 
 
		
	
		
			
				          ) ; 
 
		
	
		
			
				        }  else  { 
 
		
	
		
			
				          / /  Show  error  if  no  valid  OTP  found 
 
		
	
		
			
				          ScaffoldMessenger . of ( context ) . showSnackBar ( 
 
		
	
		
			
				            const  SnackBar ( 
 
		
	
		
			
				              content:  Text ( ' No valid OTP found in clipboard ' ) , 
 
		
	
		
			
				              duration:  Duration ( seconds:  2 ) , 
 
		
	
		
			
				            ) , 
 
		
	
		
			
				          ) ; 
 
		
	
		
			
				        } 
 
		
	
		
			
				      } 
 
		
	
		
			
				    }  catch  ( e )  { 
 
		
	
		
			
				      debugPrint ( ' Error pasting from clipboard:  $ e ' ) ; 
 
		
	
		
			
				      ScaffoldMessenger . of ( context ) . showSnackBar ( 
 
		
	
		
			
				        const  SnackBar ( 
 
		
	
		
			
				          content:  Text ( ' Failed to paste from clipboard ' ) , 
 
		
	
		
			
				          duration:  Duration ( seconds:  2 ) , 
 
		
	
		
			
				        ) , 
 
		
	
		
			
				      ) ; 
 
		
	
		
			
				    } 
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
		
			
				  @ override 
 
		
	
		
			
				  Widget  build ( BuildContext  context )  { 
 
		
	
		
			
				    return  Scaffold ( 
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -562,33 +497,28 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
 
		
	
		
			
				
 
		
	
		
			
				              / /  OTP  Input  Fields  using  new  OTP  Widget 
 
		
	
		
			
				              Center ( 
 
		
	
		
			
				                child:  AutofillGroup ( 
 
		
	
		
			
				                child:  OTPWidget ( 
 
		
	
		
			
				                  maxLength:  _otpLength , 
 
		
	
		
			
				                  controller:  _otpController , 
 
		
	
		
			
				                    pinBoxWidth:  75. h , 
 
		
	
		
			
				                    pinBoxHeight:  100. h , 
 
		
	
		
			
				                    autoFocus:  true , 
 
		
	
		
			
				                  pinBoxWidth:  70. h , 
 
		
	
		
			
				                  pinBoxHeight:  100 , 
 
		
	
		
			
				                  pinBoxRadius:  16 , 
 
		
	
		
			
				                  pinBoxBorderWidth:  0 , 
 
		
	
		
			
				                  pinBoxOuterPadding:  EdgeInsets . symmetric ( horizontal:  4. h ) , 
 
		
	
		
			
				                  defaultBorderColor:  Colors . transparent , 
 
		
	
		
			
				                  textBorderColor:  Colors . transparent , 
 
		
	
		
			
				                    errorBorderColor:  AppColors . primaryRedColor , 
 
		
	
		
			
				                  pinBoxColor:  AppColors . whiteColor , 
 
		
	
		
			
				                  autoFocus:  true , 
 
		
	
		
			
				                  onTextChanged:  _onOtpChanged , 
 
		
	
		
			
				                  pinTextStyle:  TextStyle ( 
 
		
	
		
			
				                      fontSize:  50. fSize , 
 
		
	
		
			
				                    fontSize:  4 fSize , 
 
		
	
		
			
				                    fontWeight:  FontWeight . bold , 
 
		
	
		
			
				                    color:  AppColors . whiteColor , 
 
		
	
		
			
				                  ) , 
 
		
	
		
			
				                    onTextChanged:  _onOtpChanged , 
 
		
	
		
			
				                    onDone:  _onOtpCompleted , 
 
		
	
		
			
				                  ) , 
 
		
	
		
			
				                ) , 
 
		
	
		
			
				              ) , 
 
		
	
		
			
				
 
		
	
		
			
				              const  SizedBox ( height:  16 ) , 
 
		
	
		
			
				
 
		
	
		
			
				              const  SizedBox ( height:  32 ) , 
 
		
	
		
			
				
 
		
	
		
			
				              / /  Resend  OTP 
 
		
	
		
			
				              Row ( 
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -596,9 +526,18 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
 
		
	
		
			
				                children:  [ 
 
		
	
		
			
				                  const  Text ( " Didn't receive it?  " ) , 
 
		
	
		
			
				                  if  ( _resendTime  >  0 ) 
 
		
	
		
			
				                    Text ( 
 
		
	
		
			
				                      ' resend in ( ${ _resendTime . toString ( ) . padLeft ( 2 ,  ' 0 ' ) } :00).  ' , 
 
		
	
		
			
				                    Builder ( 
 
		
	
		
			
				                      / /  Use  a  Builder  to  easily  calculate  minutes  and  seconds  inline 
 
		
	
		
			
				                      builder:  ( context )  { 
 
		
	
		
			
				                        final  minutes  =  ( _resendTime  ~ /  60 ) 
 
		
	
		
			
				                            . toString ( ) 
 
		
	
		
			
				                            . padLeft ( 2 ,  ' 0 ' ) ;  / /  Integer  division  for  minutes           final  seconds  =  ( _resendTime  %  60 ) . toString ( ) . padLeft ( 2 ,  ' 0 ' ) ;  / /  Modulo  for  remaining  seconds 
 
		
	
		
			
				                        final  seconds  =  ( _resendTime  %  60 ) . toString ( ) . padLeft ( 2 ,  ' 0 ' ) ;  / /  Modulo  for  remaining  seconds  / /  < - - -  HERE  IT  IS 
 
		
	
		
			
				                        return  Text ( 
 
		
	
		
			
				                          ' resend in ( $ minutes : $ seconds ).  ' , 
 
		
	
		
			
				                          style:  const  TextStyle ( color:  Colors . grey ) , 
 
		
	
		
			
				                        ) ; 
 
		
	
		
			
				                      } , 
 
		
	
		
			
				                    ) 
 
		
	
		
			
				                  else 
 
		
	
		
			
				                    GestureDetector ( 
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -620,50 +559,15 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
 
		
	
		
			
				    ) ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
		
			
				  void  _verifyOtp ( String  otp )  { 
 
		
	
		
			
				    debugPrint ( ' Verifying OTP:  $ otp ' ) ; 
 
		
	
		
			
				    widget . checkActivationCode ( int . parse ( otp ) ) ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
		
			
				  / / /  Auto  fill  OTP  into  text  fields 
 
		
	
		
			
				  void  autoFillOtp ( String  otp )  { 
 
		
	
		
			
				    if  ( otp . length  ! =  _otpLength )  return ; 
 
		
	
		
			
				    
 
		
	
		
			
				    / /  Clear  any  existing  text  first 
 
		
	
		
			
				    _otpController . clear ( ) ; 
 
		
	
		
			
				    
 
		
	
		
			
				    / /  Add  a  small  delay  to  ensure  the  UI  is  updated 
 
		
	
		
			
				    Future . delayed ( const  Duration ( milliseconds:  50 ) ,  ( )  { 
 
		
	
		
			
				    _isVerifying  =  false ; 
 
		
	
		
			
				    _otpController . text  =  otp ; 
 
		
	
		
			
				      / /  Move  cursor  to  the  end 
 
		
	
		
			
				      _otpController . selection  =  TextSelection . fromPosition ( 
 
		
	
		
			
				        TextPosition ( offset:  otp . length ) , 
 
		
	
		
			
				      ) ; 
 
		
	
		
			
				    } ) ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
		
			
				  / / /  Clear  OTP  fields 
 
		
	
		
			
				  void  clearOtp ( )  { 
 
		
	
		
			
				    _otpController . clear ( ) ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
		
			
				  / / /  Get  current  OTP  value 
 
		
	
		
			
				  String  getCurrentOtp ( )  { 
 
		
	
		
			
				    return  _otpController . text ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
		
			
				  / / /  Check  if  OTP  is  complete 
 
		
	
		
			
				  bool  isOtpComplete ( )  { 
 
		
	
		
			
				    return  _otpController . text . length  = =  _otpLength ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				
 
		
	
		
			
				  / / /  Simulate  SMS  received  with  OTP  ( for  testing  purposes ) 
 
		
	
		
			
				  void  simulateSMSReceived ( String  otp )  { 
 
		
	
		
			
				    if  ( otp . length  = =  _otpLength  & &  RegExp ( r'^\d+$' ) . hasMatch ( otp ) )  { 
 
		
	
		
			
				      autoFillOtp ( otp ) ; 
 
		
	
		
			
				      / /  Show  a  brief  indicator  that  SMS  was  detected 
 
		
	
		
			
				      ScaffoldMessenger . of ( context ) . showSnackBar ( 
 
		
	
		
			
				        SnackBar ( 
 
		
	
		
			
				          content:  Text ( ' OTP detected from SMS:  $ otp ' ) , 
 
		
	
		
			
				          duration:  const  Duration ( seconds:  2 ) , 
 
		
	
		
			
				          backgroundColor:  AppColors . successColor , 
 
		
	
		
			
				        ) , 
 
		
	
		
			
				      ) ; 
 
		
	
		
			
				    } 
 
		
	
		
			
				  } 
 
		
	
		
			
				}