import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:onesignal_flutter/onesignal_flutter.dart'; import '../../repositories/auth_repository.dart'; import '../../services/supabase_auth_service.dart'; // Dibutuhkan untuk DI di authRepositoryProvider import 'auth_state.dart'; // ── Provider ──────────────────────────────────────────────────── /// Provider global untuk [AuthRepository]. final authRepositoryProvider = Provider( (ref) => AuthRepository(SupabaseAuthService()), ); /// Provider utama untuk mengelola status autentikasi di seluruh aplikasi. final authProvider = StateNotifierProvider( (ref) => AuthNotifier(ref.read(authRepositoryProvider)), ); // ── Notifier ──────────────────────────────────────────────────── /// Notifier yang mengelola logika bisnis autentikasi pengguna. /// Berfungsi sebagai penghubung antara UI dan [AuthRepository], serta mengontrol pendaftaran OneSignal Push Notification. class AuthNotifier extends StateNotifier { final AuthRepository _repo; AuthNotifier(this._repo) : super(const AuthIdle()); /// Memeriksa status sesi login yang tersimpan di perangkat lokal. /// Dipanggil pertama kali saat aplikasi dibuka untuk fitur Auto-Login. Future checkAuthStatus() async { state = const AuthLoading(); try { // Mengambil sesi aktif dari repository final user = await _repo.checkSession(); if (user != null) { // Jika sesi valid, login ke OneSignal menggunakan ID user untuk pengiriman notifikasi personal OneSignal.login(user.id); state = AuthSuccess(user); } else { state = const AuthIdle(); } } catch (e) { state = const AuthIdle(); } } /// Memproses login pengguna menggunakan email dan password. Future login(String email, String password) async { state = const AuthLoading(); try { final user = await _repo.login(email, password); // Daftarkan ke OneSignal saat login berhasil OneSignal.login(user.id); state = AuthSuccess(user); } catch (e) { state = AuthError(e.toString().replaceFirst('Exception: ', '')); } } /// Memproses registrasi akun baru (Nama, Email, Password). Future register( String name, String email, String password) async { state = const AuthLoading(); try { final user = await _repo.register(name, email, password); // Daftarkan ke OneSignal saat registrasi berhasil OneSignal.login(user.id); state = AuthSuccess(user); } catch (e) { state = AuthError(e.toString().replaceFirst('Exception: ', '')); } } /// Menghubungkan akun pengguna dengan perangkat IoT ESP32 berdasarkan [claimCode] dari alat. /// Setelah berhasil diklaim, state [AuthState] akan diperbarui dengan data `deviceId` yang baru. Future claimDevice(String claimCode) async { final currentState = state; if (currentState is! AuthSuccess) return; state = const AuthLoading(); try { final deviceId = await _repo.claimDevice(currentState.user.id, claimCode); // Update UserModel dengan deviceId baru secara immutable final updatedUser = currentState.user.copyWith(deviceId: deviceId); state = AuthSuccess(updatedUser); } catch (e) { // Revert ke state sebelumnya jika terjadi error klaim state = currentState; rethrow; } } /// Keluar dari sesi login pengguna. /// Menghapus kredensial dari Supabase, memutus sesi OneSignal, dan mereset state ke [AuthIdle]. Future logout() async { OneSignal.logout(); await _repo.logout(); state = const AuthIdle(); } /// Mereset kondisi error saat ini kembali ke [AuthIdle]. void resetError() { if (state is AuthError) state = const AuthIdle(); } }