import 'dart:convert'; import 'dart:math'; import 'package:SEFER/controller/auth/captin/login_captin_controller.dart'; import 'package:SEFER/views/auth/captin/cards/egypt_card_a_i.dart'; import 'package:SEFER/views/auth/captin/register_captin.dart'; import 'package:SEFER/views/widgets/error_snakbar.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:SEFER/constant/box_name.dart'; import 'package:SEFER/constant/links.dart'; import 'package:SEFER/controller/functions/crud.dart'; import 'package:SEFER/controller/functions/ocr_controller.dart'; import 'package:SEFER/main.dart'; import 'package:SEFER/views/auth/captin/login_captin.dart'; import 'package:SEFER/views/auth/captin/verify_email_captain.dart'; import '../../../constant/colors.dart'; import '../../../views/auth/captin/ai_page.dart'; import '../../../views/auth/captin/car_license_page.dart'; import '../../../views/home/Captin/home_captain/home_captin.dart'; import '../../functions/sms_egypt_controller.dart'; class RegisterCaptainController extends GetxController { final formKey = GlobalKey(); final formKey3 = GlobalKey(); TextEditingController emailController = TextEditingController(); TextEditingController phoneController = TextEditingController(); TextEditingController passwordController = TextEditingController(); TextEditingController verifyCode = TextEditingController(); String birthDate = 'Birth Date'.tr; String gender = 'Male'.tr; bool isLoading = false; bool isSent = false; late String name; late String licenseClass; late String documentNo; late String address; late String height; late String postalCode; late String sex; late String stateCode; late String expireDate; late String dob; getBirthDate() { Get.defaultDialog( title: 'Select Date'.tr, content: SizedBox( width: 300, child: CalendarDatePicker( initialDate: DateTime.now().subtract(const Duration(days: 18 * 365)), firstDate: DateTime.parse('1940-06-01'), lastDate: DateTime.now().subtract(const Duration(days: 18 * 365)), onDateChanged: (date) { // Get the selected date and convert it to a DateTime object DateTime dateTime = date; // Call the getOrders() function from the controller birthDate = dateTime.toString().split(' ')[0]; update(); Get.back(); }, // onDateChanged: (DateTime value) {}, ), ), ); } @override void onInit() { // Get.put(SmsEgyptController()); super.onInit(); } void changeGender(String value) { gender = value; update(); } bool isValidEgyptianPhoneNumber(String phoneNumber) { // Remove any non-digit characters (spaces, dashes, etc.) phoneNumber = phoneNumber.replaceAll(RegExp(r'\D+'), ''); // Check if the phone number has exactly 11 digits if (phoneNumber.length != 11) { return false; } // Check if the phone number starts with 010, 011, 012, or 015 RegExp validPrefixes = RegExp(r'^01[0125]\d{8}$'); return validPrefixes.hasMatch(phoneNumber); } sendOtpMessage() async { SmsEgyptController smsEgyptController = Get.put(SmsEgyptController()); isLoading = true; update(); int randomNumber = Random().nextInt(100000) + 1; isLoading = true; update(); if (formKey3.currentState!.validate()) { if (box.read(BoxName.countryCode) == 'Egypt') { if (isValidEgyptianPhoneNumber(phoneController.text)) { var responseCheker = await CRUD() .post(link: AppLink.checkPhoneNumberISVerfiedDriver, payload: { 'phone_number': '+2${phoneController.text}', }); if (responseCheker != 'failure') { var d = jsonDecode(responseCheker); if (d['message'][0]['is_verified'].toString() == '1') { Get.snackbar('Phone number is verified before'.tr, '', backgroundColor: AppColor.greenColor); box.write(BoxName.phoneVerified, '1'); box.write(BoxName.phone, '+2${phoneController.text}'); await Get.put(LoginDriverController()).loginUsingCredentials( box.read(BoxName.driverID).toString(), box.read(BoxName.emailDriver).toString(), ); } else { await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: { 'phone_number': '+2${phoneController.text}', 'token_code': randomNumber.toString(), "driverId": box.read(BoxName.driverID), "email": box.read(BoxName.emailDriver), }); await smsEgyptController.sendSmsEgypt( phoneController.text.toString(), randomNumber.toString()); isSent = true; isLoading = false; update(); } } else { await CRUD().post(link: AppLink.sendVerifyOtpMessage, payload: { 'phone_number': '+2${phoneController.text}', 'token_code': randomNumber.toString(), "driverId": box.read(BoxName.driverID), "email": box.read(BoxName.emailDriver), }); await smsEgyptController.sendSmsEgypt( phoneController.text.toString(), randomNumber.toString()); isSent = true; isLoading = false; update(); } } else { mySnackeBarError( 'Phone Number wrong'.tr, ); } } } isLoading = false; update(); } DateTime? lastOtpSentTime; // Store the last OTP sent time int otpResendInterval = 300; // 5 minutes in seconds // Main function to handle OTP sending // sendOtpMessage() async { // if (_isOtpResendAllowed()) { // isLoading = true; // update(); // if (formKey3.currentState!.validate()) { // String countryCode = box.read(BoxName.countryCode); // String phoneNumber = phoneController.text; // if (countryCode == 'Egypt' && isValidEgyptianPhoneNumber(phoneNumber)) { // await _checkAndSendOtp(phoneNumber); // } else { // _showErrorMessage('Phone Number is not Egypt phone '.tr); // } // } // isLoading = false; // update(); // } else { // _showCooldownMessage(); // } // } // Check if the resend OTP request is allowed (5 minutes cooldown) // bool _isOtpResendAllowed() { // if (lastOtpSentTime == null) return true; // final int elapsedTime = // DateTime.now().difference(lastOtpSentTime!).inSeconds; // return elapsedTime >= otpResendInterval; // } // // Show message when user tries to resend OTP too soon // void _showCooldownMessage() { // int remainingTime = otpResendInterval - // DateTime.now().difference(lastOtpSentTime!).inSeconds; // Get.snackbar( // 'Please wait ${remainingTime ~/ 60}:${(remainingTime % 60).toString().padLeft(2, '0')} minutes before requesting again', // '', // backgroundColor: AppColor.redColor, // ); // } // // Check if the phone number has been verified, and send OTP if not verified // _checkAndSendOtp(String phoneNumber) async { // var responseChecker = await CRUD().post( // link: AppLink.checkPhoneNumberISVerfiedDriver, // payload: { // 'phone_number': '+2$phoneNumber', // }, // ); // if (responseChecker != 'failure') { // var responseData = jsonDecode(responseChecker); // if (_isPhoneVerified(responseData)) { // _handleAlreadyVerified(); // } else { // await _sendOtpAndSms(phoneNumber); // } // } else { // await _sendOtpAndSms(phoneNumber); // } // } // Check if the phone number is already verified bool _isPhoneVerified(dynamic responseData) { return responseData['message'][0]['is_verified'].toString() == '1'; } // Handle case where phone number is already verified _handleAlreadyVerified() { mySnackbarSuccess('Phone number is already verified'.tr); box.write(BoxName.phoneVerified, '1'); box.write(BoxName.phone, '+2${phoneController.text}'); Get.put(LoginDriverController()).loginUsingCredentials( box.read(BoxName.driverID).toString(), box.read(BoxName.emailDriver).toString(), ); } // Send OTP and SMS _sendOtpAndSms(String phoneNumber) async { SmsEgyptController smsEgyptController = Get.put(SmsEgyptController()); int randomNumber = Random().nextInt(100000) + 1; await CRUD().post( link: AppLink.sendVerifyOtpMessage, payload: { 'phone_number': '+2$phoneNumber', 'token_code': randomNumber.toString(), 'driverId': box.read(BoxName.driverID), 'email': box.read(BoxName.emailDriver), }, ); await smsEgyptController.sendSmsEgypt(phoneNumber, randomNumber.toString()); lastOtpSentTime = DateTime.now(); // Update the last OTP sent time isSent = true; isLoading = false; update(); } // Show error message in case of invalid phone number void _showErrorMessage(String message) { mySnackeBarError(message); } verifySMSCode() async { if (formKey3.currentState!.validate()) { var res = await CRUD().post(link: AppLink.verifyOtpDriver, payload: { 'phone_number': '+2${phoneController.text}', 'token_code': verifyCode.text.toString(), }); if (res != 'failure') { // var dec = jsonDecode(res); box.write(BoxName.phoneDriver, '+2${phoneController.text}'); box.write(BoxName.phoneVerified, '1'); // var res1 = await CRUD().post( // link: AppLink.updateAccountBank, // payload: {'phone': '+2${phoneController.text}'}); // if (res1 != 'failure') { Get.find().isGoogleLogin == true ? await Get.put(LoginDriverController()) .loginUsingCredentialsWithoutGoogle( Get.find() .passwordController .text .toString(), box.read(BoxName.emailDriver).toString(), ) : await Get.put(LoginDriverController()).loginUsingCredentials( box.read(BoxName.driverID).toString(), box.read(BoxName.emailDriver).toString(), ); // Get.to(EgyptCardAI()); // } else { // Get.snackbar('title', 'message'); // } } } else { mySnackeBarError('you must insert token code '.tr); } } sendVerifications() async { var res = await CRUD().post(link: AppLink.verifyEmail, payload: { 'email': emailController.text.isEmpty ? Get.find().emailController.text.toString() : emailController.text, 'token': verifyCode.text, }); if (res != 'failure') { if (Get.find().emailController.text.toString() != '') { Get.offAll(() => HomeCaptain()); } else { Get.to(() => CarLicensePage()); } } } void nextToAIDetection() async { //Todo dont forget this if (formKey.currentState!.validate()) { isLoading = true; update(); Get.to(() => AiPage()); } } Map payloadLisence = {}; void getFromController() { name = Get.find().name; licenseClass = Get.find().licenseClass.toString(); documentNo = Get.find().documentNo.toString(); address = Get.find().address.toString(); height = Get.find().height.toString(); postalCode = Get.find().address.toString(); sex = Get.find().sex.toString(); stateCode = Get.find().postalCode.toString(); expireDate = Get.find().expireDate.toString(); dob = Get.find().dob.toString(); update(); } Future addLisence() async { getFromController(); var res = await CRUD().post(link: AppLink.addLicense, payload: { 'name': name, 'licenseClass': licenseClass, 'documentNo': documentNo, 'address': address, 'height': height, 'postalCode': postalCode, 'sex': sex, 'stateCode': stateCode, 'expireDate': expireDate, 'dateOfBirth': dob, }); isLoading = false; update(); if (jsonDecode(res)['status'] == 'success') { // Get.to(() => AiPage()); //todo rplace this } } void addRegisrationCarForDriver(String vin, make, model, year, color, owner, expirationDate, registrationDate) async { getFromController(); var res = await CRUD().post(link: AppLink.addRegisrationCar, payload: { 'vin': vin, 'make': make, 'model': model, 'year': year, 'expirationDate': expirationDate, 'color': color, 'owner': owner, 'registrationDate': registrationDate, }); box.write(BoxName.vin, vin); box.write(BoxName.make, make); box.write(BoxName.model, model); box.write(BoxName.year, year); box.write(BoxName.expirationDate, expirationDate); box.write(BoxName.color, color); box.write(BoxName.owner, owner); box.write(BoxName.registrationDate, registrationDate); isLoading = false; update(); if (jsonDecode(res)['status'] == 'success') { Get.offAll(() => LoginCaptin()); //todo replace this } } Future register() async { getFromController(); if (formKey.currentState!.validate()) { isLoading = true; update(); var res = await CRUD().post(link: AppLink.signUpCaptin, payload: { 'first_name': name.split(' ')[1], 'last_name': name.split(' ')[0], 'email': emailController.text, 'phone': phoneController.text, 'password': passwordController.text, 'gender': sex, 'site': address, 'birthdate': dob, }); isLoading = false; update(); if (jsonDecode(res)['status'] == 'success') { box.write(BoxName.driverID, jsonDecode(res)['message']); box.write(BoxName.dobDriver, dob); box.write(BoxName.sexDriver, sex); box.write(BoxName.phoneDriver, phoneController.text); box.write(BoxName.lastNameDriver, name.split(' ')[0]); int randomNumber = Random().nextInt(100000) + 1; await CRUD().post(link: AppLink.sendVerifyEmail, payload: { 'email': emailController.text, 'token': randomNumber.toString(), }); Get.to(() => VerifyEmailCaptainPage()); } } } }