// import 'dart:convert'; // import 'package:onufitness/constants/constant.dart'; // import 'package:onufitness/models/general/get_agora_user_trm_token_response_model.dart'; // import 'package:onufitness/models/login_response_model.dart'; // import 'package:onufitness/models/user_details_response_model.dart'; // import 'package:onufitness/screens/u_vault/models/failed_videos_draft_model.dart'; // class SharedServices { // //............................................................................. // static Future setLoginDetails(LoginResponseModel? responseModel) async { // if (responseModel != null) { // preferences!.setString( // "login_details", // jsonEncode(responseModel.toJson()), // ); // } // } // //............................................................................. // static bool isLoggedIn() { // return preferences?.getString("login_details") != null ? true : false; // } // static bool isUserDataExist() { // return preferences?.getString("user_details") != null ? true : false; // } // //............................................................................. // static LoginResponseModel? getLoginDetails() { // if (preferences!.getString("login_details") != null) { // return LoginResponseModel.fromJson( // jsonDecode(preferences!.getString("login_details")!), // ); // } else { // return null; // } // } // //............................................................................. // static Future logout() async { // //..................................... // // await preferences!.clear(); // //..................................... // await preferences?.remove('login_details'); // await preferences?.remove('user_details'); // //..................................... // await preferences?.remove('agora_user_rtm_token'); // await preferences?.remove('failed_uploads'); // return true; // } // //............................................................................. // static String userAuth() { // var model = LoginResponseModel.fromJson( // jsonDecode(preferences!.getString("login_details")!), // ); // return "Bearer ${model.data?.tokenResponse?.accessToken}"; // } // //............................................................................. // // Set User Details............................................................ // static Future setUserDetails( // UserDetailsResponseModel? responseModel, // ) async { // if (responseModel != null) { // preferences!.setString( // "user_details", // jsonEncode(responseModel.toJson()), // ); // } // } // //............................................................................. // // Get User Details............................................................ // static UserDetailsResponseModel? getUserDetails() { // if (preferences!.getString("user_details") != null) { // return UserDetailsResponseModel.fromJson( // jsonDecode(preferences!.getString("user_details")!), // ); // } else { // return null; // } // } // //...........Draft Videos.................................................................. // //............................................................................. // static Future addFailedUpload(FailedUploadModel model) async { // final current = preferences!.getStringList("failed_uploads") ?? []; // final modelJson = jsonEncode(model.toJson()); // if (!(current.any((e) => e.contains(model.title)) || // current.any((e) => e.contains(model.videoFilePath)))) { // current.add(modelJson); // await preferences!.setStringList("failed_uploads", current); // } // } // static List getFailedUploads() { // final data = preferences!.getStringList("failed_uploads") ?? []; // return data.map((e) => FailedUploadModel.fromJson(jsonDecode(e))).toList(); // } // static Future removeFailedUploadAt(int index) async { // final list = preferences!.getStringList("failed_uploads") ?? []; // if (index >= 0 && index < list.length) { // list.removeAt(index); // await preferences!.setStringList("failed_uploads", list); // } // } // //............................................................................. // //............................................................................. // // Agora Details............................................................ // static Future setAgoraToken( // AgoraUserAndRtmTokenResponseModel? responseModel, // ) async { // if (responseModel != null) { // preferences!.setString( // "agora_user_rtm_token", // jsonEncode(responseModel.toJson()), // ); // } // } // static AgoraUserAndRtmTokenResponseModel? getAgoraUserAndRtmTokens() { // if (preferences!.getString("agora_user_rtm_token") != null) { // return AgoraUserAndRtmTokenResponseModel.fromJson( // jsonDecode(preferences!.getString("agora_user_rtm_token")!), // ); // } else { // return null; // } // } // //............................................................................. // // MVP Popup - show once per day........................................... // static bool shouldShowMvpPopup() { // final lastShown = preferences?.getString('mvp_last_shown_date'); // final today = DateTime.now().toLocal(); // final todayStr = // '${today.year}-${today.month.toString().padLeft(2, '0')}-${today.day.toString().padLeft(2, '0')}'; // return lastShown != todayStr; // } // static Future markMvpPopupShownToday() async { // final today = DateTime.now().toLocal(); // final todayStr = // '${today.year}-${today.month.toString().padLeft(2, '0')}-${today.day.toString().padLeft(2, '0')}'; // await preferences?.setString('mvp_last_shown_date', todayStr); // } // } //======================================================================================================================== //............. Above one is Final working till 27-03-2026 ............................................................................ //======================================================================================================================== import 'dart:convert'; import 'package:onufitness/constants/constant.dart'; import 'package:onufitness/models/general/get_agora_user_trm_token_response_model.dart'; import 'package:onufitness/models/login_response_model.dart'; import 'package:onufitness/models/user_details_response_model.dart'; import 'package:onufitness/screens/u_vault/models/failed_videos_draft_model.dart'; import 'package:onufitness/services/local_storage_services/registration_fields_save_model.dart' show ProfileDraft; class SharedServices { //............................................................................. static Future setLoginDetails(LoginResponseModel? responseModel) async { if (responseModel != null) { preferences!.setString( "login_details", jsonEncode(responseModel.toJson()), ); } } //............................................................................. static bool isLoggedIn() { return preferences?.getString("login_details") != null ? true : false; } static bool isUserDataExist() { return preferences?.getString("user_details") != null ? true : false; } static LoginResponseModel? getLoginDetails() { if (preferences!.getString("login_details") != null) { return LoginResponseModel.fromJson( jsonDecode(preferences!.getString("login_details")!), ); } else { return null; } } static Future logout() async { await preferences?.remove('login_details'); await preferences?.remove('user_details'); await preferences?.remove('agora_user_rtm_token'); await preferences?.remove('failed_uploads'); await clearProfileDraft(); return true; } static String userAuth() { var model = LoginResponseModel.fromJson( jsonDecode(preferences!.getString("login_details")!), ); return "Bearer ${model.data?.tokenResponse?.accessToken}"; } static Future setUserDetails( UserDetailsResponseModel? responseModel, ) async { if (responseModel != null) { preferences!.setString( "user_details", jsonEncode(responseModel.toJson()), ); } } static UserDetailsResponseModel? getUserDetails() { if (preferences!.getString("user_details") != null) { return UserDetailsResponseModel.fromJson( jsonDecode(preferences!.getString("user_details")!), ); } else { return null; } } static Future addFailedUpload(FailedUploadModel model) async { final current = preferences!.getStringList("failed_uploads") ?? []; final modelJson = jsonEncode(model.toJson()); if (!(current.any((e) => e.contains(model.title)) || current.any((e) => e.contains(model.videoFilePath)))) { current.add(modelJson); await preferences!.setStringList("failed_uploads", current); } } static List getFailedUploads() { final data = preferences!.getStringList("failed_uploads") ?? []; return data.map((e) => FailedUploadModel.fromJson(jsonDecode(e))).toList(); } static Future removeFailedUploadAt(int index) async { final list = preferences!.getStringList("failed_uploads") ?? []; if (index >= 0 && index < list.length) { list.removeAt(index); await preferences!.setStringList("failed_uploads", list); } } static Future setAgoraToken( AgoraUserAndRtmTokenResponseModel? responseModel, ) async { if (responseModel != null) { preferences!.setString( "agora_user_rtm_token", jsonEncode(responseModel.toJson()), ); } } static AgoraUserAndRtmTokenResponseModel? getAgoraUserAndRtmTokens() { if (preferences!.getString("agora_user_rtm_token") != null) { return AgoraUserAndRtmTokenResponseModel.fromJson( jsonDecode(preferences!.getString("agora_user_rtm_token")!), ); } else { return null; } } static bool shouldShowMvpPopup() { final lastShown = preferences?.getString('mvp_last_shown_date'); final today = DateTime.now().toLocal(); final todayStr = '${today.year}-${today.month.toString().padLeft(2, '0')}-${today.day.toString().padLeft(2, '0')}'; return lastShown != todayStr; } static Future markMvpPopupShownToday() async { final today = DateTime.now().toLocal(); final todayStr = '${today.year}-${today.month.toString().padLeft(2, '0')}-${today.day.toString().padLeft(2, '0')}'; await preferences?.setString('mvp_last_shown_date', todayStr); } // ======================================================================================================================== // Profile Draft — persists both Create Profile screen AND // Create Final Account screen form data. // ======================================================================================================================== static const _kProfileDraft = 'profile_draft'; /// Merges only the supplied keys into the persisted draft. /// Omitted keys are left untouched, so partial saves are always safe. static Future saveProfileDraft({ // ── Identity ───────────────────────────────────────────── String? email, // ── Screen 1: Create Profile ────────────────────────────── String? firstName, String? lastName, String? phoneNumber, String? countryCode, String? selectedDate, String? selectedDateDisplay, String? genderName, int? genderId, String? countryName, int? countryId, String? stateName, int? stateId, String? cityName, int? cityId, bool? isTermsAccepted, bool? isDataConsentAccepted, // ── Screen 2: Create Final Account ─────────────────────── String? workoutTypeName, int? workoutTypeId, String? fitnessGoalName, int? fitnessGoalId, String? dietaryPreferenceName, int? dietaryPreferenceId, List? healthConditionNames, List? healthConditionIds, }) async { final existing = _loadRawDraft(); // Identity if (email != null) existing['email'] = email; // Screen 1 if (firstName != null) existing['firstName'] = firstName; if (lastName != null) existing['lastName'] = lastName; if (phoneNumber != null) existing['phoneNumber'] = phoneNumber; if (countryCode != null) existing['countryCode'] = countryCode; if (selectedDate != null) existing['selectedDate'] = selectedDate; if (selectedDateDisplay != null) { existing['selectedDateDisplay'] = selectedDateDisplay; } if (genderName != null) existing['genderName'] = genderName; if (genderId != null) existing['genderId'] = genderId; if (countryName != null) existing['countryName'] = countryName; if (countryId != null) existing['countryId'] = countryId; if (stateName != null) existing['stateName'] = stateName; if (stateId != null) existing['stateId'] = stateId; if (cityName != null) existing['cityName'] = cityName; if (cityId != null) existing['cityId'] = cityId; if (isTermsAccepted != null) existing['isTermsAccepted'] = isTermsAccepted; if (isDataConsentAccepted != null) { existing['isDataConsentAccepted'] = isDataConsentAccepted; } // Screen 2 if (workoutTypeName != null) existing['workoutTypeName'] = workoutTypeName; if (workoutTypeId != null) existing['workoutTypeId'] = workoutTypeId; if (fitnessGoalName != null) existing['fitnessGoalName'] = fitnessGoalName; if (fitnessGoalId != null) existing['fitnessGoalId'] = fitnessGoalId; if (dietaryPreferenceName != null) { existing['dietaryPreferenceName'] = dietaryPreferenceName; } if (dietaryPreferenceId != null) { existing['dietaryPreferenceId'] = dietaryPreferenceId; } if (healthConditionNames != null) { existing['healthConditionNames'] = healthConditionNames; } if (healthConditionIds != null) { existing['healthConditionIds'] = healthConditionIds; } await preferences?.setString(_kProfileDraft, jsonEncode(existing)); } static Map _loadRawDraft() { final raw = preferences?.getString(_kProfileDraft); if (raw == null || raw.isEmpty) return {}; try { return Map.from(jsonDecode(raw)); } catch (_) { return {}; } } static ProfileDraft? getProfileDraft() { final map = _loadRawDraft(); if (map.isEmpty) return null; return ProfileDraft.fromMap(map); } static bool hasProfileDraft() => _loadRawDraft().isNotEmpty; static Future clearProfileDraft() async { await preferences?.remove(_kProfileDraft); } }