import 'package:e_porter/_core/utils/snackbar/snackbar_helper.dart'; import 'package:e_porter/data/repositories/auth_repository_impl.dart'; import 'package:e_porter/domain/models/user_entity.dart'; import 'package:e_porter/domain/usecases/auth_usecase.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../_core/service/logger_service.dart'; import '../../_core/service/preferences_service.dart'; import '../screens/routes/app_rountes.dart'; class AuthController extends GetxController { final LoginUseCase loginUseCase; final GetUserRoleUseCase getUserRoleUseCase; final GetUserDataUseCase getUserDataUseCase; final RegisterUseCase registerUseCase; final SaveUserDataUseCase saveUserDataUseCase; final SendResetEmailUseCase sendResetEmailUseCase; final ConfirmResetPasswordUseCase confirmResetPasswordUseCase; final emailController = TextEditingController(); final passwordController = TextEditingController(); var isLoading = false.obs; var errorMessage = ''.obs; AuthController({ required this.loginUseCase, required this.getUserRoleUseCase, required this.getUserDataUseCase, required this.registerUseCase, required this.saveUserDataUseCase, required this.sendResetEmailUseCase, required this.confirmResetPasswordUseCase, }); Future login({String? roleFromOnboarding}) async { errorMessage.value = ''; if (emailController.text.isEmpty || passwordController.text.isEmpty) { SnackbarHelper.showError("Error", "Email/Password tidak boleh kosong"); return; } isLoading.value = true; try { final userEntity = await loginUseCase( emailController.text, passwordController.text, ); final uid = userEntity.uid; final roleFromDB = await getUserRoleUseCase(uid); logger.d("roleFromDB: $roleFromDB, roleFromOnboarding: $roleFromOnboarding, UID: $uid"); if (roleFromDB != null && roleFromOnboarding != null && roleFromDB != roleFromOnboarding) { SnackbarHelper.showError( "Role Tidak Sesuai", "Akun ini terdaftar sebagai '$roleFromDB', bukan '$roleFromOnboarding'."); return; } final effectiveRole = roleFromDB ?? roleFromOnboarding ?? 'penumpang'; final userData = await getUserDataUseCase(uid); if (userData == null) { SnackbarHelper.showError("Login Gagal", "Data user tidak ditemukan."); return; } if (userData.role!.toLowerCase() != effectiveRole.toLowerCase()) { SnackbarHelper.showError( "Role Tidak Sesuai", "Data user menunjukkan role '${userData.role}', bukan '$effectiveRole'."); return; } emailController.clear(); passwordController.clear(); await PreferencesService.saveUserData(userData); Get.offAllNamed(Routes.NAVBAR, arguments: effectiveRole); } on AuthException catch (e) { if (e.message == 'email-not-verified') { SnackbarHelper.showError( "Verifikasi Diperlukan", "Silakan cek email Anda dan klik link verifikasi sebelum login.", ); } else { SnackbarHelper.showError( "Login Gagal", "Email atau password anda salah.", ); } } catch (e) { SnackbarHelper.showError("Terjadi Kesalahan", e.toString()); } finally { isLoading.value = false; } } Future register({ required String name, required String email, required String password, required String role, }) async { errorMessage.value = ''; isLoading.value = true; try { final userEntity = await registerUseCase( email.trim(), password, ); final userData = UserData( uid: userEntity.uid, tipeId: null, noId: null, name: name.trim(), email: email.trim(), phone: null, birthDate: null, gender: null, work: null, city: null, address: null, role: role, ); await saveUserDataUseCase(userData); SnackbarHelper.showSuccess( "Berhasil", "Akun berhasil dibuat. Silakan cek email Anda untuk verifikasi terlebih dahulu.", ); Get.offNamed(Routes.VERIFICATION); } on AuthException catch (e) { switch (e.message) { case 'weak-password': SnackbarHelper.showError("Error", "Password terlalu lemah."); break; case 'email-already-in-use': SnackbarHelper.showError("Error", "Email sudah terdaftar."); break; case 'invalid-email': SnackbarHelper.showError("Error", "Format email tidak valid."); break; default: SnackbarHelper.showError("Registrasi Gagal", "Terjadi kesalahan saat registrasi."); } } catch (e) { SnackbarHelper.showError("Terjadi Kesalahan", e.toString()); } finally { isLoading.value = false; } } Future resendEmailVerification() async { final user = FirebaseAuth.instance.currentUser; if (user == null) { SnackbarHelper.showError("Error", "User tidak ditemukan."); return; } if (user.emailVerified) { SnackbarHelper.showSuccess("Sudah Terverifikasi", "Email Anda sudah terverifikasi."); return; } try { await user.sendEmailVerification(); SnackbarHelper.showSuccess( "Terkirim", "Link verifikasi telah dikirim ulang ke email Anda.", ); } on FirebaseException catch (e) { if (e.message?.contains('No AppCheckProvider') == true) { SnackbarHelper.showSuccess( "Terkirim", "Link verifikasi telah dikirim ulang ke email Anda.", ); } else { SnackbarHelper.showError( "Gagal", "Gagal mengirim ulang verifikasi. Silakan coba lagi.", ); } } catch (e) { SnackbarHelper.showError( "Gagal", "Gagal mengirim ulang verifikasi. Silakan coba lagi.", ); } } Future completeEmailVerification() async { final user = FirebaseAuth.instance.currentUser; if (user == null) return; await user.reload(); if (user.emailVerified) { final userData = await getUserDataUseCase(user.uid); if (userData != null) { await PreferencesService.saveUserData(userData); } Get.offAllNamed(Routes.NAVBAR, arguments: userData?.role); } } Future sendResetEmail(String email) async { try { await sendResetEmailUseCase(email.trim()); SnackbarHelper.showSuccess( "Silahkan Cek Email", "Link reset password telah dikirim ke $email.", ); } on AuthException catch (e) { SnackbarHelper.showError("Gagal", e.message); } } Future resetPassword(String code, String newPassword) async { try { await confirmResetPasswordUseCase(code, newPassword); SnackbarHelper.showSuccess( "Berhasil", "Password berhasil diubah. Silakan login kembali.", ); Get.offAllNamed(Routes.LOGIN); } on AuthException catch (e) { SnackbarHelper.showError("Gagal", e.message); } } }