import 'dart:async'; import 'dart:io'; import 'dart:math'; import 'package:country_currency_pickers/country.dart'; import 'package:country_currency_pickers/utils/utils.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:http/http.dart'; import 'package:http/http.dart' as dio1; import 'package:http/http.dart' as http; import 'package:intl/intl.dart'; import 'package:otp_timer_button/otp_timer_button.dart'; import 'package:rounded_loading_button_plus/rounded_loading_button.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:sms_autofill/sms_autofill.dart'; import '../../Data/Repository/Authentication/loginrepository.dart'; import '../../Helper/Constants/Colorconstants.dart'; import '../../Helper/Logger.dart'; import '../../Helper/toast.dart'; import '../../Model/Request/Authentication/Loginrequest.dart'; import '../../Model/Response/Authentication/Loginresponse.dart'; import '../../View/Authentication/Otpverification.dart'; import '../../View/Authentication/Usercreate/Usercreateview.dart'; class AuthController extends GetxController with CodeAutoFill{ String? formatter; String? currencyCode; String? fcmEntryToken; String? resendOtp; String? userFcmToken; String? contactNo; //Otp String? smsOtp; String verifyId = ""; int authmode = 0; bool termsChecking =false; //Otp bool codeSent = false; var loginStatus; String? contactLength; // FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance; FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance; Country selectedDialogCountry = CountryPickerUtils.getCountryByIsoCode('IN'); // final RoundedLoadingButtonController btnController = RoundedLoadingButtonController(); final RoundedLoadingButtonController loginController = RoundedLoadingButtonController(); //Otp OtpTimerButtonController otpTimerController = OtpTimerButtonController(); TextEditingController loginPhoneNumberController = TextEditingController(); TextEditingController otpController = TextEditingController(); TextEditingController textEditingController = TextEditingController(); LoginRepository loginRepository = LoginRepository(); @override void onInit() { getId(); fcmToken(); listenForCode(); super.onInit(); } @override void onClose() { cancel(); /// Stop listening for the OTP code super.onClose(); } @override void codeUpdated() { otpController.text = code ?? ''; logger.i("OTP Code Received: ${otpController.text}"); } @override void dispose() { // TODO: implement dispose SmsAutoFill().unregisterListener(); loginPhoneNumberController.dispose(); otpController.dispose(); super.dispose(); } fcmToken() async { SharedPreferences prefs = await SharedPreferences.getInstance(); var token = await firebaseMessaging.getToken(); logger.i("firebase token======$token"); fcmEntryToken = token; prefs.setString('fcmToken', token!); logger.i("tenanttokensetstring ${prefs.getString('fcmToken')}"); } void currency() async { SharedPreferences prefs = await SharedPreferences.getInstance(); currencyCode = prefs.getString('Code_Currency')!; final formats = NumberFormat(); formatter = formats.simpleCurrencySymbol("$currencyCode"); prefs.setString('Currency_Symbol', formatter!); } void loginTenant(context) async { Timer(const Duration(seconds: 1), () { // btnController.success(); profileValidation(context); }); } profileValidation(context)async{ if (loginPhoneNumberController.text.isEmpty) { loginController.reset(); Toast.showToast("Please Enter Mobile Number"); } else if (!RegExp( r'^\s*(?:\+?(\d{1,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *x(\d+))?\s*$') .hasMatch(loginPhoneNumberController.text)) { loginController.reset(); Toast.showToast("Please Enter a Valid Phone Number"); } else if(termsChecking==false){ loginController.reset(); Toast.showToast("Please Select Terms of Service"); } else { signIn(context); } } String? uniqueDeviceId; String? deviceId; var iosDeviceInfo; var androidDeviceInfo; Future getId() async { // var deviceInfo = DeviceInfoPlugin(); SharedPreferences prefs = await SharedPreferences.getInstance(); if (Platform.isIOS) { // import 'dart:io' // iosDeviceInfo = await deviceInfo.iosInfo; deviceId = iosDeviceInfo.toMap().toString(); uniqueDeviceId = iosDeviceInfo.id; prefs.setString('deviceId',uniqueDeviceId!); print('iosDeviceInfodeviceId$deviceId'); print('uniqueDeviceId${prefs.getString('deviceId')}'); return iosDeviceInfo.identifierForVendor; // Unique ID on iOS } else { // androidDeviceInfo = await deviceInfo.androidInfo; deviceId = androidDeviceInfo.toMap().toString(); uniqueDeviceId = androidDeviceInfo.id; prefs.setString('deviceId',uniqueDeviceId!); print('androidDeviceInfodeviceId$deviceId'); print('uniqueDeviceId${prefs.getString('deviceId')}'); return androidDeviceInfo.androidId; // Unique ID on Android } print('${deviceId =androidDeviceInfo.androidId}'); } //Authentication signIn(context) async { SharedPreferences prefs = await SharedPreferences.getInstance(); // ✅ Ensure FCM token is ready before calling API if (fcmEntryToken == null) { await fcmToken(); } // Prepare data final contactNo = loginPhoneNumberController.text; final configId = 1; final deviceType = Platform.operatingSystem; final fcmTokenValue = fcmEntryToken ?? ''; final deviceId1 = deviceId ?? ''; // ✅ Print all values before sending print("========= LOGIN REQUEST DATA ========="); print("📱 Contact No : $contactNo"); print("⚙️ Config ID : $configId"); print("💻 Device Type : $deviceType"); print("🔑 FCM Token : $fcmTokenValue"); print("🆔 Device ID : $deviceId1"); print("======================================"); // Call login API loginApi( LoginRequest( contactno: contactNo, configid: configId, devicetype: deviceType, userfcmtoken: fcmTokenValue, deviceid: deviceId1, ), context, ); } loginApi(LoginRequest data,context) async { SharedPreferences prefs = await SharedPreferences.getInstance(); LoginResponse? result = await loginRepository.signIn(data); if (result?.status == true) { loginStatus = result?.status; authmode = result?.details?.authmode??0; userFcmToken = result?.details?.userfcmtoken; contactNo = result?.details?.contactno; logger.i('loginApilocationname ${result?.details?.locationname}'); prefs.setInt('userId', result?.details?.userid ?? 0); prefs.setString('authName', result?.details?.authname ?? ''); prefs.setInt('configId', result?.details?.configid ?? 0); prefs.setInt('authMode', result?.details?.authmode ?? 0); prefs.setInt('roleId', result?.details?.roleid ?? 0); prefs.setString('userFirstName', result?.details?.firstname ?? ''); prefs.setString('userLastName', result?.details?.lastname ?? ''); prefs.setString('userPassword', result?.details?.password ?? ''); prefs.setString('userEmail', result?.details?.email ?? ''); // prefs.setString('tenantContactNo', result?.details?.contactno ?? ''); prefs.setString('address', result?.details?.address ?? ''); prefs.setString('userSuburb', result?.details?.suburb ?? ''); prefs.setString('userCity', result?.details?.city ?? ''); prefs.setString('userState', result?.details?.state ?? ''); prefs.setString('userPostcode', result?.details?.postcode ?? ''); // prefs.setString('tenantFcmToken', result?.details?.userfcmtoken ?? ''); prefs.setInt('userPin', result?.details?.pin ?? 0); prefs.setInt('partnerId', result?.details?.partnerid ?? 0); prefs.setInt('tenantId', result?.details?.tenantid ?? 0); prefs.setString('userName', result?.details?.fullname ?? ''); prefs.setString('tenantName', result?.details?.tenantname ?? ''); prefs.setString('tenantAddress', result?.details?.tenantaddress ?? ''); prefs.setString('tenantCity', result?.details?.tenantcity ?? ''); prefs.setString('tenantPostcode', result?.details?.tenantpostcode ?? ''); prefs.setString('tenantLatitude', result?.details?.tenantlat ?? ''); prefs.setString('tenantLongitude', result?.details?.tenantlong ?? ''); prefs.setInt('locationId', result?.details?.locationid ?? 0); prefs.setString('locationName', result?.details?.locationname ?? ''); prefs.setString('appLocation', result?.details?.applocation ?? ''); prefs.setString('appLatitude', result?.details?.applatitude ?? ''); prefs.setString('appLongitude', result?.details?.applongitude ?? ''); prefs.setInt('appRadius', result?.details?.appradius ?? 0); prefs.setInt('appLocationId', result?.details?.applocationid ?? 0); prefs.setInt('moduleId', result?.details?.moduleid ?? 0); logger.i('App location Id from login : ${prefs.getInt('appLocationId')}'); logger.i('location Id from login : ${prefs.getInt('locationId')}'); update(); } if(authmode !=1) { sendSmsOtp('${loginPhoneNumberController.text.trim()}', authmode: result?.details?.authmode ?? 0); } else{ otpController.clear(); resendOtp = '123456'; if(authmode==1){ var snackBar = SnackBar( backgroundColor: ColorConstants.primaryColor, duration: const Duration(seconds: 5), content: Text('Please enter your 6 digit verification code provided by Nearlexpress Business',style: TextStyle(color: ColorConstants.secondaryColor),) ); ScaffoldMessenger.of(context).showSnackBar(snackBar); } Get.to(()=>OTPVerification(otp: '$resendOtp' ,authmode: authmode,logInStatus:loginStatus ,)); } loginController.reset(); } //Otp sendSmsOtp(String mobile, {authmode=0}) async { int otpInput = await otpGenerator(); smsOtp = otpInput.toString(); if(authmode==1) { onNavigateToProfileNumberVerification(otp: "123456",authmode: authmode); } else { receiveSmsOtp(mobile,smsOtp.toString(), Get.context); } } Future receiveSmsOtp(String phoneNumber, String otp, context) async { final appSignature = await SmsAutoFill().getAppSignature; final message = "<#> Dear customer, use OTP $otp to sign in to Nearle App.\n$appSignature"; final encodedMessage = Uri.encodeComponent(message); final url = Uri.parse( 'https://msg.lionsms.com/api/smsapi?' 'key=e57f5c9679af26077be1a7eadabb1b2a' '&route=7' '&sender=NEARLE' '&number=$phoneNumber' '&sms=$encodedMessage' '&templateid=1107174712357438611', ); logger.i('urlsendOtp $url'); logger.i('appSignaturereceiveSmsOtp $appSignature'); try { final response = await http.get(url); if (response.statusCode == 200) { logger.i("SMS sent successfully"); receiveOtp(response, otp); } else { logger.i("Failed to send SMS: ${response.body}"); } } catch (e) { logger.i("Error sending SMS: $e"); } } receiveOtp(model,otp) async{ onNavigateToProfileNumberVerification(otp: otp); } onNavigateToProfileNumberVerification({String? otp,authmode=0}){ otpController.clear(); print('onNavigateToProfileNumberVerification $otp'); resendOtp = otp; Get.to(()=>OTPVerification(otp: resendOtp??'' ,authmode: authmode,logInStatus: loginStatus,)); } otpGenerator(){ var rng = Random(); var next = rng.nextDouble() * 1000000; while (next < 100000) { next *= 10; } print(next.toInt()); print("random${next.toInt()}"); return next.toInt(); } Future getHintPhoneNumber(context) async { try { final phoneNumber = await SmsAutoFill().hint; if (phoneNumber != null) { // Remove +91 from the phone number String cleanedPhoneNumber = phoneNumber.startsWith('+91') ? phoneNumber.substring(3) : phoneNumber; loginPhoneNumberController.text = cleanedPhoneNumber; contactLength = cleanedPhoneNumber; // doSomething(context); update(); logger.i("Phone number retrieved: ${loginPhoneNumberController.text}"); } } catch (e) { logger.i("Failed to retrieve phone number hint: $e"); } } }