// ignore_for_file: prefer_single_quotes import 'dart:convert'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:tm_app/core/constants/pref_keys.dart'; import 'package:tm_app/core/utils/logger.dart'; import 'package:tm_app/data/services/api/auth_api.dart'; import 'package:tm_app/data/services/model/customer/customer.dart'; import 'package:tm_app/data/services/model/forgot_password_response/forgot_password_response_model.dart'; import 'package:tm_app/data/services/model/login_response/login_response_model.dart'; import 'package:tm_app/data/services/model/logout_response/logout_response.dart'; import 'package:tm_app/data/services/model/reset_password_response/reset_password_response.dart'; import 'package:tm_app/data/services/model/verify_otp_response/verify_otp_response_model.dart'; import '../../core/network/network_manager.dart'; import '../../core/utils/result.dart'; class AuthService { AuthService({required NetworkManager networkManager}) : _networkManager = networkManager; final NetworkManager _networkManager; Future> login({ required String username, required String password, }) async { //get device fcm token with error handling String fcmToken = ''; try { final FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance; await firebaseMessaging.requestPermission(); fcmToken = await firebaseMessaging.getToken() ?? ''; AppLogger().info('📱 FCM Token retrieved successfully'); } catch (e) { AppLogger().error('❌ Failed to get FCM token: $e'); fcmToken = ''; } var data = jsonEncode({ "password": password, "username": username, "device_token": fcmToken, }); final result = await _networkManager.makeRequest( AuthApi.login, method: 'POST', (json) => LoginResponseModel.fromJson(json), data: data, ); if (result is Ok) { final prefs = await SharedPreferences.getInstance(); final token = result.value.data.accessToken; AppLogger().info('🔑 Bearer token: $token'); final refreshToken = result.value.data.refreshToken; final customer = result.value.data.customer; await prefs.setString(PrefKeys.bearer, token!); await prefs.setString(PrefKeys.refreshToken, refreshToken!); // Save customer data as JSON string if (customer != null) { final customerJson = jsonEncode(customer.toJson()); await prefs.setString(PrefKeys.customerData, customerJson); AppLogger().info('👤 Customer data saved to preferences'); } } return result; } Future> logout() async { final result = await _networkManager.makeRequest( AuthApi.logout, method: 'DELETE', (json) => LogoutResponse.fromJson(json), ); // Clear local data after successful logout if (result is Ok) { await localLogout(); } return result; } Future> resetPassword({ required String newPassword, required String token, }) async { var data = jsonEncode({"new_password": newPassword, "token": token}); final result = await _networkManager.makeRequest( AuthApi.resetPassword, method: 'POST', (json) => ResetPasswordResponse.fromJson(json), data: data, ); return result; } Future localLogout() async { final prefs = await SharedPreferences.getInstance(); await prefs.remove(PrefKeys.bearer); await prefs.remove(PrefKeys.refreshToken); await prefs.remove(PrefKeys.customerData); appLogger.info('tokens and customer data cleared!'); } Future> forgotPassword({ required String email, }) async { final data = jsonEncode({"email": email}); final result = await _networkManager.makeRequest( AuthApi.forgotPassword, method: 'POST', (json) => ForgotPasswordResponseModel.fromJson(json), data: data, ); return result; } Future> verifyOtp({ required String code, required String email, }) async { final data = jsonEncode({"code": code, "email": email}); final result = await _networkManager.makeRequest( AuthApi.forgotPasswordOtp, method: 'POST', (json) => VerifyOtpResponseModel.fromJson(json), data: data, ); return result; } Future> checkIsLoggedIn() async { final prefs = await SharedPreferences.getInstance(); final token = prefs.getString(PrefKeys.bearer); if (token == null) { return const Result.ok(false); } return const Result.ok(true); } Future getStoredCustomer() async { final prefs = await SharedPreferences.getInstance(); final customerJson = prefs.getString(PrefKeys.customerData); if (customerJson == null) { return null; } try { final customerMap = jsonDecode(customerJson) as Map; return Customer.fromJson(customerMap); } catch (e) { AppLogger().error('❌ Failed to parse stored customer data: $e'); return null; } } }