// ignore_for_file: non_constant_identifier_names import 'dart:convert'; import 'dart:developer'; import 'dart:io'; import 'package:wanisclient/config/AppSnackbar.dart'; import 'package:wanisclient/services/push_notification_service.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart' as http; import 'package:http_parser/http_parser.dart'; import '../config/api_response.dart'; import '../config/constants/app_constant.dart'; import '../config/constants/consts.dart'; import '../models/login_request_model.dart'; import '../models/login_response.dart'; import '../models/social_response.dart'; import '../models/users.dart'; import '../providers/utils_singleton.dart'; class AuthServices { int statusCode = -1; bool errorToken = false; Future> socialLoginMissingData( String deviceId, String deviceType, String ip) async { errorToken = false; statusCode = -1; final prefs = await SharedPreferences.getInstance(); var tokenData = prefs.getString("token"); String? fcmToken; await PushNotificationService().getFCMToken(); fcmToken = prefs.getString("FCM token"); log(fcmToken ?? "NoToken"); try { var request = http.MultipartRequest( "POST", Uri.https(baseUrl, '/api/v1/user/add_missing_social_data')); Map headers = { 'Authorization': 'Bearer $tokenData', 'Accept': 'application/json', "Content-type": "multipart/form-data", }; request.headers.addAll(headers); request.fields['deviceId'] = deviceId; request.fields['deviceType'] = deviceType; request.fields['ip'] = ip; request.fields['tokendevice'] = fcmToken ?? ""; log("------------- Request logs --------------"); log("------> Request Header : ${request.headers}"); log("------> Request fields : ${request.fields}"); log("------> Request start here :"); http.Response response = await http.Response.fromStream(await request.send()); statusCode = response.statusCode; if (response.statusCode == 200 || response.statusCode == 201) { final jsonData = json.decode(response.body); SocialDataUser data = SocialDataUser.fromJson(jsonData); return APIResponse(statusCode: statusCode, data: data); } else { Future.microtask(() async => await logError( errorCode: statusCode.toString(), errorMessage: response.body, path: '/api/v1/user/add_missing_social_data')); return APIResponse(statusCode: statusCode, errorMessage: response.body); } } catch (e) { Future.microtask(() async => await logError( errorCode: statusCode.toString(), errorMessage: "Caught error : $e", path: '/api/v1/user/add_missing_social_data', )); return APIResponse(statusCode: statusCode, errorMessage: "Sign in error"); } } Future> signIn(String email, String password, String? deviceId, String? deviceType, String? ip) async { // Initialize SharedPreferences instance only once. final prefs = await SharedPreferences.getInstance(); errorToken = false; statusCode = -1; // Retrieve or fetch FCM token efficiently String fcmToken = prefs.getString("FCM token") ?? await _getOrFetchFCMToken(prefs); log("FCM Token: $fcmToken"); // Construct the login request model final userLogin = LoginRequestModel( email: email, password: password, deviceId: deviceId, deviceType: deviceType, ip: ip, tokendevice: fcmToken, ); if (baseUrl == null || baseUrl.isEmpty) { return APIResponse( statusCode: 500, errorMessage: "URL for sign-in cannot be null or empty"); } // Attempt to parse URI with error handling late Uri uri; try { uri = Uri.https(baseUrl, '/api/v1/auth/signin'); } catch (e) { log("Error parsing URL: $e"); return APIResponse( statusCode: 500, errorMessage: "Invalid URL for sign-in"); } try { // Define headers as a constant to improve performance const headers = { 'Content-type': 'application/json', 'Accept': 'application/json', }; // Send HTTP request final response = await http.post( uri, headers: headers, body: jsonEncode(userLogin.toJson()), ); statusCode = response.statusCode; if (statusCode == 200 || statusCode == 201) { final jsonData = json.decode(utf8.decode(response.bodyBytes)); LoginResponse loginResponse = LoginResponse.fromJson(jsonData); // Ensure roles are authorized if (loginResponse.roles == "ROLE_SUPPLIER" || loginResponse.roles == "ROLE_ADMIN") { return APIResponse( statusCode: 401, errorMessage: "Unauthorized Access"); } // Batch update SharedPreferences for better performance await Future.wait([ prefs.setString('token', loginResponse.token!), prefs.setString('refreshToken', loginResponse.refreshtoken!), prefs.setString('Email', email), prefs.setString('Password', password), prefs.setString('Role', loginResponse.roles!), prefs.setBool("isLoggedIn", true), ]); return APIResponse( statusCode: statusCode, data: loginResponse); } // Log error details and return failure response await _logErrorDetails(response); return APIResponse( statusCode: statusCode, errorMessage: response.body); } catch (err, stacktrace) { log("-------> Sign In Error : $err"); await logError( errorCode: "500", errorMessage: "Caught error : $err", path: '/api/v1/auth/signin'); return APIResponse( statusCode: 500, errorMessage: 'No internet connection'); } } // Function to retrieve or fetch the FCM token Future _getOrFetchFCMToken(SharedPreferences prefs) async { String? fcmToken = prefs.getString("FCM token"); if (fcmToken == null || fcmToken.isEmpty) { await PushNotificationService().getFCMToken(); fcmToken = prefs.getString("FCM token") ?? "InvalidToken"; } return fcmToken; } // Function to log error details Future _logErrorDetails(http.Response response) async { await logError( errorCode: response.statusCode.toString(), errorMessage: response.body, path: '/api/v1/auth/signin', ); } Future logError( {String? comment, required String errorCode, required String errorMessage, required String path}) async { errorToken = false; statusCode = -1; final Map query = { "clientid": "283386", "comment": comment ?? "No comment provided", "errorcode": errorCode, "errormessage": errorMessage, "path": path, "source": "MOBILE_APP", "useremail": utils.user?.email ?? "email@email.com", // [email@email.com] this email is for user not logged in "username": utils.user?.name ?? "anonymous user", "userphonenumber": utils.user?.phoneNumber ?? "00000000", }; return await http.post( Uri.https(AppString.reportLink, 'api/v1/servererror/new_error', query), headers: { 'Content-type': 'application/json', 'Accept': 'application/json' }, ).then((data) async { statusCode = data.statusCode; if (data.statusCode == 200 || data.statusCode == 201) { return APIResponse(statusCode: statusCode); } return APIResponse( statusCode: statusCode, errorMessage: 'Please check your info'); }).catchError((_) { return APIResponse( statusCode: statusCode, errorMessage: 'no internet connection'); }); } Future fetchAgoraToken(String channelName, int uid) async { // IMPORTANT: Replace with your server's actual URL const String serverUrl = "https://$baseUrl/api/agora/token"; final urlres = Uri.parse('$serverUrl?channelName=$channelName&uid=$uid'); // 1. Get your user's authentication token // This is the token that proves the user is logged into YOUR app. final String? userAuthToken = utils.token??"InvalidToken"; // 2. Create the headers map final Map headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer $userAuthToken', // Add the token here }; try { // 3. Pass the headers to the http.get call final response = await http.get(urlres, headers: headers); if (response.statusCode == 200) { if (response.body.isNotEmpty) { final body = jsonDecode(response.body); // if backend included a token field, we're already signed in if (body is Map && body.containsKey('token')) { final token = body['token'] as String; return APIResponse(statusCode: response.statusCode, data: token); } } return APIResponse( statusCode: response.statusCode, errorMessage: 'Please check your info', ); } else { print("⛔️ Failed to fetch token. Status code: ${response.statusCode}"); print("⛔️ Response body: ${response.body}"); return APIResponse( statusCode: response.statusCode, errorMessage: 'Please check your info', ); } } catch (e) { print("⛔️ Error fetching token: $e"); return APIResponse( statusCode: 500, errorMessage: 'Please check your info', ); } } Future> getCurrentUser() async { errorToken = false; statusCode = -1; return await http.get( Uri.https(baseUrl, '/api/v1/user/current_user'), headers: { 'Authorization': 'Bearer ${utils.token}', 'Content-type': 'application/json', 'Accept': 'application/json' }, ).then((data) async { statusCode = data.statusCode; if (data.statusCode == 200 || data.statusCode == 201) { final codeUnits = data.body.codeUnits; var str = const Utf8Decoder().convert(codeUnits); final jsonData = json.decode(str); log("Token: ${utils.token}"); users profile = users.fromJson(jsonData); log(profile.toJson().toString()); return APIResponse(statusCode: statusCode, data: profile); } Future.microtask(() async => await logError( errorCode: statusCode.toString(), errorMessage: data.body, path: '/api/v1/user/current_user')); return APIResponse( statusCode: statusCode, errorMessage: 'Please check your info'); }).catchError((err, stacktrace) { log("-------> fetch profile Error :"); log(err.toString()); Future.microtask(() async => await logError( errorCode: statusCode.toString(), errorMessage: "Caught error : $err", path: '/api/v1/user/current_user')); log("stacktrace : $stacktrace"); return APIResponse( statusCode: statusCode, errorMessage: 'no internet connection', ); }); } Future updateProfilePicture(File image, int userId) async { // Replace with your base URL // Replace with your token retrieval logic // Prepare multipart request log('2'); final request = http.MultipartRequest( 'PATCH', Uri.https(baseUrl, '/api/v1/user/update_user_profile_image'), ); // Set headers final Map headers = { 'Authorization': 'Bearer ${utils.token}', 'Accept': 'application/json', 'Content-type': 'multipart/form-data', }; request.headers.addAll(headers); // Prepare multipart file final multipartFile = http.MultipartFile( 'file', image.readAsBytes().asStream(), image.lengthSync(), filename: image.uri.pathSegments.last, contentType: MediaType( 'image', image.uri.pathSegments.last.split('.').last, ), ); request.files.add(multipartFile); // Send request final response = await request.send(); final http.Response httpResponse = await http.Response.fromStream(response); // Handle response if (httpResponse.statusCode == 200 || httpResponse.statusCode == 201) { // Success log("update profile image${httpResponse.body}"); return APIResponse( statusCode: httpResponse.statusCode, data: jsonDecode(httpResponse.body)); } else { // Log and return error log(httpResponse.statusCode.toString()); return APIResponse( statusCode: httpResponse.statusCode, errorMessage: 'Please check your info', ); } } Future updateProfile(Map updatedFields) async { // Create request headers final Map headers = { 'Authorization': 'Bearer ${utils.token}', 'Accept': 'application/json', 'Content-Type': 'application/json', }; print('*-*-*-*-*-*--------------------------------$updatedFields'); // Create URI final uri = Uri.https(baseUrl, '/api/v1/user/update_current_user_profile_data'); try { // Send PATCH request final response = await http.patch( uri, headers: headers, body: jsonEncode(updatedFields), ); // Handle response if (response.statusCode == 200 || response.statusCode == 201) { log("Update profile response: ${response.body}"); return APIResponse( statusCode: response.statusCode, data: jsonDecode(response.body), ); } else { log("Error: ${response.statusCode}"); return APIResponse( statusCode: response.statusCode, errorMessage: 'Please check your info', ); } } catch (e) { log("Exception: $e"); return APIResponse( statusCode: 500, errorMessage: 'An unexpected error occurred', ); } } Future sendsimplesmsverification(String phonenumber) async { // Create request headers final Map headers = { 'Authorization': 'Bearer ${utils.token}', 'Accept': 'application/json', 'Content-Type': 'application/json', }; print('*-*-*-*-*-*--------------------------------$phonenumber'); // Create URI final uri = Uri.https(baseUrl, '/api/v1/user/send-otp',{ 'phonenumber': phonenumber, },); try { // Send PATCH request final response = await http.post( uri, headers: headers, ); // Handle response if (response.statusCode == 200 || response.statusCode == 201) { log("Update profile response: ${response.body}"); return APIResponse( statusCode: response.statusCode, data: true, ); } else { log("Error: ${response.statusCode}"); return APIResponse( statusCode: response.statusCode, data: false, errorMessage: 'Please check your info', ); } } catch (e) { log("Exception: $e"); return APIResponse( statusCode: 500, data: false, errorMessage: 'An unexpected error occurred', ); } } Future verifyphonenumber(String phonenumber,String otp) async { // Create request headers final Map headers = { 'Authorization': 'Bearer ${utils.token}', 'Accept': 'application/json', 'Content-Type': 'application/json', }; print('*-*-*-*-*-*--------------------------------$phonenumber'); // Create URI final uri = Uri.https(baseUrl, '/api/v1/user/sms/verifyOtp',{ 'phonenumberreq': phonenumber, 'otpreq': otp, },); try { // Send PATCH request final response = await http.post( uri, headers: headers, ); // Handle response if (response.statusCode == 200 || response.statusCode == 201) { log("Update profile response: ${response.body}"); return APIResponse( statusCode: response.statusCode, data: true, ); } else { log("Error: ${response.statusCode}"); return APIResponse( statusCode: response.statusCode, data: false, errorMessage: 'Please check your info', ); } } catch (e) { log("Exception: $e"); return APIResponse( statusCode: 500, data: false, errorMessage: 'An unexpected error occurred', ); } } Future> refreshToken() async { final prefs = await SharedPreferences.getInstance(); String? refreshToken = prefs.getString('refreshToken'); if (refreshToken == null) { return APIResponse( errorMessage: 'No refresh token available', ); } final uri = Uri.https( baseUrl, '/api/v1/auth/refreshtoken', ); final response = await http.post( uri, headers: { 'Content-type': 'application/json', 'Accept': 'application/json', }, body: json.encode({'refreshToken': refreshToken, 'token': utils.token}), ); APIResponse apiResponse = APIResponse(); apiResponse.statusCode = response.statusCode; apiResponse.dataJson = response.body; if (response.statusCode == 200) { final data = json.decode(response.body); String newToken = data['token']; String newRefreshToken = data['refreshToken']; // Save the new tokens prefs.setString('token', newToken); prefs.setString('refreshToken', newRefreshToken); apiResponse.data = newToken; } else { apiResponse.errorMessage = 'Failed to refresh token'; } return apiResponse; } Future phoneSignUP(String inPhoneNumber, String dToken) async { try { final response = await http.post( Uri.https(baseUrl, '/api/auth_otp/send-otp'), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: jsonEncode( {"phoneNumber": "+$inPhoneNumber", "devicetoken": dToken}), ); if (response.statusCode == 200 || response.statusCode == 201) { return APIResponse(statusCode: response.statusCode, data: response); } else { return APIResponse( statusCode: response.statusCode, errorMessage: 'Please check your info', ); } } catch (e, stackTrace) { log("Error: $e"); log("StackTrace: $stackTrace"); return APIResponse( statusCode: 500, errorMessage: 'No internet connection'); } } Future phoneSignUPOtpWhatsapp(String inPhoneNumber, String dToken) async { try { final response = await http.post( Uri.https(baseUrl, '/api/auth_otp/send-otp-whatsapp'), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: jsonEncode( {"phoneNumber": "+$inPhoneNumber", "devicetoken": dToken}), ); if (response.statusCode == 200 || response.statusCode == 201) { return APIResponse(statusCode: response.statusCode, data: response); } else { return APIResponse( statusCode: response.statusCode, errorMessage: 'Please check your info', ); } } catch (e, stackTrace) { log("Error: $e"); log("StackTrace: $stackTrace"); return APIResponse( statusCode: 500, errorMessage: 'No internet connection'); } } Future phoneForgetPassword(String inPhoneNumber) async { try { final response = await http.post( Uri.https(baseUrl, '/api/auth_otp/reset_password_first_step', {"phoneNumber": "+$inPhoneNumber"}), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, ); if (response.statusCode == 200 || response.statusCode == 201) { return APIResponse(statusCode: response.statusCode, data: response); } else { return APIResponse( statusCode: response.statusCode, errorMessage: 'Please check your info', ); } } catch (e, stackTrace) { log("Error: $e"); log("StackTrace: $stackTrace"); return APIResponse( statusCode: 500, errorMessage: 'No internet connection'); } } Future phoneForgetPasswordWhatsapp(String inPhoneNumber) async { try { final response = await http.post( Uri.https(baseUrl, '/api/auth_otp/reset_password_first_step_whatsapp', {"phoneNumber": "+$inPhoneNumber"}), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, ); if (response.statusCode == 200 || response.statusCode == 201) { return APIResponse(statusCode: response.statusCode, data: response); } else { return APIResponse( statusCode: response.statusCode, errorMessage: 'Please check your info', ); } } catch (e, stackTrace) { log("Error: $e"); log("StackTrace: $stackTrace"); return APIResponse( statusCode: 500, errorMessage: 'No internet connection'); } } Future> isPhoneNumberExist(String inPhoneNumber) async { try { final response = await http.get( Uri.https( baseUrl, '/api/v1/public/exist_user_by_phone_number', {"phoneNumber": "+$inPhoneNumber"}, ), headers: { 'Accept': 'application/json', }, ); if (response.statusCode == 200 || response.statusCode == 201) { // The API returns literally: true OR false final body = response.body.trim().toLowerCase(); final exists = body == "true"; return APIResponse( statusCode: response.statusCode, data: exists, dataJson: response.body, ); } else { return APIResponse( statusCode: response.statusCode, errorMessage: 'Please check your info', ); } } catch (e, stackTrace) { log("Error: $e"); log("StackTrace: $stackTrace"); return APIResponse( statusCode: 500, errorMessage: 'No internet connection', ); } } Future ChangePassword(String password) async { try { final response = await http.patch( Uri.https( baseUrl, '/api/v1/user/update_my_password', {'password': password}, ), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ${utils.token}', }, ); log("response : ${response.body}"); if (response.statusCode == 200 || response.statusCode == 201) { log("response : ${response.body}"); if (response.body == "password updated successfully") { // Corrected: Pass the response.body string instead of the entire response object return APIResponse( statusCode: response.statusCode, data: response.body); } // If the API had a JSON body with a token, this part would handle it // if (response.body.isNotEmpty && response.body.startsWith('{')) { // final body = jsonDecode(response.body); // if (body is Map && body.containsKey('token')) { // final token = body['token'] as String; // return APIResponse(statusCode: response.statusCode, data: token); // } // } // Corrected: Default to passing the response body string return APIResponse( statusCode: response.statusCode, data: response.body); } else { // Pass the error message from the response body if available return APIResponse( statusCode: response.statusCode, errorMessage: response.body.isNotEmpty ? response.body : 'Please check your info', ); } } catch (e, stackTrace) { log("Error: $e"); log("StackTrace: $stackTrace"); return APIResponse( statusCode: 500, errorMessage: 'No internet connection'); } } Future resetPassword(String newPassword, String phonenumber, String code) async { try { final response = await http.post( Uri.https( baseUrl, '/api/auth_otp/change_password_final_step', { 'newPassword': newPassword, 'code': code, 'phonenumber': "+${phonenumber}", }, ), headers: { 'Accept': 'application/json', }, ); log("response : ${response.body}"); if (response.statusCode == 200 || response.statusCode == 201) { return APIResponse( statusCode: response.statusCode, data: response.body, ); } else { return APIResponse( statusCode: response.statusCode, errorMessage: response.body.isNotEmpty ? response.body : 'Please check your info', ); } } catch (e, stackTrace) { log("Error: $e"); log("StackTrace: $stackTrace"); return APIResponse( statusCode: 500, errorMessage: 'No internet connection', ); } } Future phoneLogin( String inPhoneNumber, String dToken, String password) async { try { final response = await http.post( Uri.https(baseUrl, '/api/v1/auth/signin'), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: jsonEncode({ "username": "+$inPhoneNumber", "tokendevice": dToken, "password": password }), ); if (response.statusCode == 200 || response.statusCode == 201) { log("response : ${response.body}"); if (response.body.isNotEmpty) { final body = jsonDecode(response.body); // if backend included a token field, we're already signed in if (body is Map && body.containsKey('token')) { var prefs = await SharedPreferences.getInstance(); final token = body['token'] as String; await prefs.setString('token', token); await prefs.setString('refreshToken', "INVALID"); utils.updatetoken(token); return APIResponse(statusCode: response.statusCode, data: token); } } return APIResponse(statusCode: response.statusCode, data: response); } else { return APIResponse( statusCode: response.statusCode, errorMessage: 'Please check your info', ); } } catch (e, stackTrace) { log("Error: $e"); log("StackTrace: $stackTrace"); return APIResponse( statusCode: 500, errorMessage: 'No internet connection'); } } Future> verifyCodeauth( String inPhone, String inOTPCode, String? deviceId, String? deviceType, String? ip, String dToken) async { // await PushNotificationService().getFCMToken(); // var fcmToken = util.prefs!.getString("FCM token"); // final loginData = { // "deviceId": deviceId, // "deviceType": deviceType, // "ip": ip, // "otp": inOTPCode, // "phoneNo": inPhone, // "tokendevice": fcmToken ?? "", // "role": "ROLE_USER" // }; final loginData = { "deviceId": deviceId, "deviceType": deviceType, "ip": ip, "otp": inOTPCode, "phoneNo": "+$inPhone", "tokendevice": dToken }; return await http .post( Uri.https(baseUrl, 'api/auth_otp/verify-otp-twillio-auth'), headers: { 'Content-type': 'application/json', 'Accept': 'application/json' }, body: jsonEncode(loginData), ) .then((data) async { statusCode = data.statusCode; log(statusCode.toString()); if (statusCode == 200 || statusCode == 201) { final jsonData = json.decode(data.body); log("Verification result: \n $jsonData"); final response = LoginResponse.fromJson(jsonData); var prefs = await SharedPreferences.getInstance(); // await util.prefs!.setBool("isLoggedIn", true); // await util.prefs!.setString("Role", response.roles!); await prefs.setString('token', response.token!); await prefs.setString('refreshToken', response.refreshtoken!); utils.updatetoken(response.token!); return APIResponse( statusCode: statusCode, data: response); }else if(statusCode == 423 ){ AppSnackbar.showError("Error", "operation is pending"); } else if(statusCode == 406 ){ AppSnackbar.showError("Error", "operation is canceled"); } else if(statusCode == 429 ){ AppSnackbar.showError("Error", "max attempts reached"); } else if(statusCode == 301 ){ AppSnackbar.showError("Error", "OTP is deleted"); } else if(statusCode == 400 ){ AppSnackbar.showError("Error", "operation is failed"); } else if(statusCode == 408 ){ AppSnackbar.showError("Error", "OTP is expired"); } return APIResponse( statusCode: statusCode, errorMessage: 'Please check your info'); }).catchError((_, stack) { log(stack.toString()); return APIResponse(statusCode: statusCode); }); } Future> verifyCode( String inPhone, String inOTPCode, String? deviceId, String? deviceType, String? ip, String dToken) async { // await PushNotificationService().getFCMToken(); // var fcmToken = util.prefs!.getString("FCM token"); // final loginData = { // "deviceId": deviceId, // "deviceType": deviceType, // "ip": ip, // "otp": inOTPCode, // "phoneNo": inPhone, // "tokendevice": fcmToken ?? "", // "role": "ROLE_USER" // }; final loginData = { "deviceId": deviceId, "deviceType": deviceType, "ip": ip, "otp": inOTPCode, "phoneNo": "+$inPhone", "tokendevice": dToken }; return await http .post( Uri.https(baseUrl, 'api/auth_otp/sms/verifyOtp'), headers: { 'Content-type': 'application/json', 'Accept': 'application/json' }, body: jsonEncode(loginData), ) .then((data) async { statusCode = data.statusCode; log(statusCode.toString()); if (statusCode == 200 || statusCode == 201) { final jsonData = json.decode(data.body); log("Verification result: \n $jsonData"); final response = LoginResponse.fromJson(jsonData); var prefs = await SharedPreferences.getInstance(); // await util.prefs!.setBool("isLoggedIn", true); // await util.prefs!.setString("Role", response.roles!); await prefs.setString('token', response.token!); await prefs.setString('refreshToken', response.refreshtoken!); utils.updatetoken(response.token!); return APIResponse( statusCode: statusCode, data: response); } return APIResponse( statusCode: statusCode, errorMessage: 'Please check your info'); }).catchError((_, stack) { log(stack.toString()); return APIResponse(statusCode: statusCode); }); } Future> validateResetPasswordOTP( String inPhone, String inOTPCode, ) async { log("phonenumber +$inPhone"); log("inOTPCode $inOTPCode"); try { final uri = Uri.https( baseUrl, 'api/auth_otp/validate_reset_code_second_step', { "phonenumber": "+$inPhone", "reset_code": inOTPCode, }, ); final response = await http.post( uri, headers: { 'Content-type': 'application/json', 'Accept': 'application/json' }, ); statusCode = response.statusCode; log("Status code: $statusCode"); if (statusCode == 200) { final jsonData = json.decode(response.body); log("Verification result: \n $jsonData"); return APIResponse(statusCode: statusCode, data: jsonData); } return APIResponse( statusCode: statusCode, errorMessage: 'Invalid reset code or phone number', ); } catch (e, stack) { log("Error: $e\n$stack"); return APIResponse(statusCode: statusCode); } } Future logOut() async { try { final response = await http.put( Uri.https(baseUrl, '/api/v1/user/logout'), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ${utils.token}', }, body: jsonEncode({}), // FIXED ); print("*-*-*-*-*- ${response.statusCode} +++${response.body}"); if (response.statusCode == 200 || response.statusCode == 201) { return APIResponse(statusCode: response.statusCode); } else { return APIResponse( statusCode: response.statusCode, errorMessage: "Bad request", ); } } catch (e, stack) { print(stack); return APIResponse(statusCode: 500, errorMessage: e.toString()); } } Future deleteUser() async { print( "*-*-*-*-*- ---------------------------------------------------------------------01"); try { final response = await http.post( Uri.https(baseUrl, '/api/v1/user/delete_user'), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ${utils.token}', }, body: jsonEncode({}), // FIXED ); print( "*-*-*-*-*- ---------------------------------------------------------------------02"); print("*-*-*-*-*- ${response.statusCode} +++${response.body}"); if (response.statusCode == 200 || response.statusCode == 201) { return APIResponse(statusCode: response.statusCode); } else { return APIResponse( statusCode: response.statusCode, errorMessage: "Bad request", ); } } catch (e, stack) { print( "*-*-*-*-*- ---------------------------------------------------------------------04"); print(stack); return APIResponse(statusCode: 500, errorMessage: e.toString()); } } Future phoneTextLogin(String inPhoneNumber, String dToken) async { try { final response = await http.post( Uri.https(baseUrl, '/api/auth_otp/send-otp-twillio-auth'), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: jsonEncode( {"phoneNumber": "+$inPhoneNumber", "devicetoken": dToken}), ); if (response.statusCode == 200 || response.statusCode == 201) { log("response : ${response.body}"); if (response.body.isNotEmpty) { // Try to parse as JSON try { final body = jsonDecode(response.body); // if backend included a token field, we're already signed in if (body is Map && body.containsKey('token')) { var prefs = await SharedPreferences.getInstance(); final token = body['token'] as String; await prefs.setString('token', token); await prefs.setString('refreshToken', "INVALID"); utils.updatetoken(token); return APIResponse(statusCode: response.statusCode, data: body); } // Return parsed JSON body (even if no token) return APIResponse(statusCode: response.statusCode, data: body); } catch (e) { log("Response is not JSON, treating as plain text: $e"); // If JSON parsing fails, return a map indicating OTP was sent return APIResponse( statusCode: response.statusCode, data: {"status": response.body.trim()} ); } } return APIResponse( statusCode: response.statusCode, data: {"status": "success"} ); } if(response.statusCode == 403){ return APIResponse( statusCode: response.statusCode, errorMessage: 'your account is disabled', ); } if(response.statusCode == 301){ return APIResponse( statusCode: response.statusCode, errorMessage: 'Account is deleted', ); } if(response.statusCode == 423){ return APIResponse( statusCode: response.statusCode, errorMessage: 'Account is blocked', ); } else { return APIResponse( statusCode: response.statusCode, errorMessage: 'Please check your info', ); } } catch (e, stackTrace) { log("Error: $e"); log("StackTrace: $stackTrace"); return APIResponse( statusCode: 500, errorMessage: 'No internet connection'); } } Future addReferral(String code) async { // Create request headers final Map headers = { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'Bearer ${utils.token}', }; print('*-*-*-*-*-*--------------------------------$code'); // Create URI final uri = Uri.https(baseUrl, '/api/v1/referral_code/add_referral',{ 'code': code, },); try { // Send PATCH request final response = await http.post( uri, headers: headers, ); // Handle response if (response.statusCode == 200 || response.statusCode == 201) { log("addReferral: ${response.body}"); return APIResponse( statusCode: response.statusCode, data: true, ); } else if (response.statusCode == 226) { log("Error: ${response.statusCode}"); return APIResponse( statusCode: response.statusCode, data: false, errorMessage: 'You already have a referral', ); } else if (response.statusCode == 406) { log("Error: ${response.statusCode}"); return APIResponse( statusCode: response.statusCode, data: false, errorMessage: 'This code is not exist', ); } else { log("Error: ${response.statusCode}"); return APIResponse( statusCode: response.statusCode, data: false, errorMessage: 'Please check your info', ); } } catch (e) { log("Exception: $e"); return APIResponse( statusCode: 500, data: false, errorMessage: 'An unexpected error occurred', ); } } }