import 'dart:async'; import 'package:flutter/material.dart'; import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_livestock/data/common/dio_exception_handeler.dart'; import 'package:rasadyar_livestock/data/model/request/login_request/login_request_model.dart'; import 'package:rasadyar_livestock/data/model/response/auth/auth_response_model.dart'; import 'package:rasadyar_livestock/data/repository/auth/auth_repository.dart' show AuthRepository; import 'package:rasadyar_livestock/injection/live_stock_di.dart'; import 'package:rasadyar_livestock/presentation/routes/app_pages.dart'; import 'package:rasadyar_livestock/presentation/widgets/captcha/logic.dart'; enum AuthType { useAndPass, otp } enum AuthStatus { init } enum OtpStatus { init, sent, verified, reSend } class AuthLogic extends GetxController with GetTickerProviderStateMixin { GlobalKey formKey = GlobalKey(); late AnimationController _textAnimationController; late Animation textAnimation; RxBool showCard = false.obs; RxBool rememberMe = false.obs; Rx> formKeyOtp = GlobalKey().obs; Rx> formKeySentOtp = GlobalKey().obs; Rx usernameController = TextEditingController().obs; Rx passwordController = TextEditingController().obs; Rx phoneOtpNumberController = TextEditingController().obs; Rx otpCodeController = TextEditingController().obs; var captchaController = Get.find(); RxnString phoneNumber = RxnString(null); RxBool isLoading = false.obs; RxBool isDisabled = true.obs; TokenStorageService tokenStorageService = Get.find(); Rx authType = AuthType.useAndPass.obs; Rx authStatus = AuthStatus.init.obs; Rx otpStatus = OtpStatus.init.obs; RxInt secondsRemaining = 120.obs; Timer? _timer; AuthRepository authRepository = diLiveStock.get(); final Module _module = Get.arguments; @override void onInit() { super.onInit(); _textAnimationController = AnimationController(vsync: this, duration: const Duration(milliseconds: 1200)) ..repeat(reverse: true, count: 2).whenComplete(() { showCard.value = true; }); textAnimation = CurvedAnimation(parent: _textAnimationController, curve: Curves.easeInOut); } @override void onClose() { _timer?.cancel(); super.onClose(); } void startTimer() { _timer?.cancel(); secondsRemaining.value = 120; _timer = Timer.periodic(const Duration(seconds: 1), (timer) { if (secondsRemaining.value > 0) { secondsRemaining.value--; } else { timer.cancel(); } }); } void stopTimer() { _timer?.cancel(); } String get timeFormatted { final minutes = secondsRemaining.value ~/ 60; final seconds = secondsRemaining.value % 60; return '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}'; } bool _isFormValid() { final isCaptchaValid = captchaController.formKey.currentState?.validate() ?? false; final isFormValid = formKey.currentState?.validate() ?? false; return isCaptchaValid && isFormValid; } LoginRequestModel _buildLoginRequest() { final phone = usernameController.value.text; final pass = passwordController.value.text; final code = captchaController.textController.value.text; final key = captchaController.captchaKey.value; return LoginRequestModel.createWithCaptcha( username: phone, password: pass, captchaCode: code, captchaKey: key!, ); } Future submitLoginForm() async { if (!_isFormValid()) return; final loginRequestModel = _buildLoginRequest(); isLoading.value = true; await safeCall( call: () async => await authRepository.login(authRequest: loginRequestModel.toJson()), onSuccess: (result) async { await tokenStorageService.saveModule(_module); await tokenStorageService.saveRefreshToken(_module,result?.refresh ?? ''); await tokenStorageService.saveAccessToken(_module,result?.access ?? ''); if (rememberMe.value) { await tokenStorageService.saveUserPass( _module, usernameController.value.text, passwordController.value.text, ); } Get.offAllNamed(LiveStockRoutes.init); }, onError: (error, stackTrace) { if (error is DioException) { diLiveStock.get().handle(error); } captchaController.getCaptcha(); }, ); isLoading.value = false; } }