import 'package:flutter/material.dart'; import 'package:tm_app/data/services/model/customer/customer.dart'; import '../core/utils/logger.dart'; import '../core/utils/result.dart'; import '../data/repositories/auth_repository.dart'; import '../data/services/model/login_response/login_response_model.dart'; class AuthViewModel with ChangeNotifier { final AuthRepository _authRepository; AuthViewModel({required AuthRepository authRepository}) : _authRepository = authRepository { usernameController.addListener(_onTextChanged); passwordController.addListener(_onTextChanged); } final TextEditingController usernameController = TextEditingController(); final TextEditingController passwordController = TextEditingController(); final FocusNode usernameFocus = FocusNode(); final FocusNode passwordFocus = FocusNode(); bool _obscurePassword = true; bool get obscurePassword => _obscurePassword; // bool get isLoginEnabled => // usernameController.text.isNotEmpty && passwordController.text.isNotEmpty; // Auth state bool _isLoading = false; bool _isLoggedIn = false; String? _errorMessage; Customer? _loggedInUser; String? successMessage; Role? _userRole; bool get isLoading => _isLoading; bool get isLoggedIn => _isLoggedIn; String? get errorMessage => _errorMessage; Customer? get loggedInUser => _loggedInUser; Role? get userRole => _userRole; void togglePasswordVisibility() { _obscurePassword = !_obscurePassword; notifyListeners(); } Future hydrateFromStorage() async { try { final customer = await _authRepository.getStoredCustomer(); if (customer != null) { _loggedInUser = customer; _userRole = customer.role == 'admin' ? Role.admin : Role.analyst; notifyListeners(); } } catch (e) { AppLogger().error('❌ Failed to hydrate auth state: $e'); } } // void _onTextChanged() { // notifyListeners(); // } bool _isLoginEnabled = false; bool get isLoginEnabled => _isLoginEnabled; void _onTextChanged() { final newValue = usernameController.text.isNotEmpty && passwordController.text.isNotEmpty; if (newValue != _isLoginEnabled) { _isLoginEnabled = newValue; notifyListeners(); } } Future login() async { _isLoading = true; _errorMessage = null; notifyListeners(); await localLogout(); final result = await _authRepository.login( username: usernameController.text.trim(), password: passwordController.text.trim(), ); switch (result) { case Ok(): _loggedInUser = result.value.data.customer; _userRole = _loggedInUser?.role == 'admin' ? Role.admin : Role.analyst; usernameController.clear(); passwordController.clear(); break; case Error(): _errorMessage = result.error.toString(); notifyListeners(); break; } _isLoading = false; _errorMessage = null; notifyListeners(); } Future localLogout() async { try { await _authRepository.localLogout(); } catch (e) { // Handle local logout exceptions gracefully AppLogger().error('❌ Failed to local logout: $e'); } _loggedInUser = null; _isLoggedIn = false; notifyListeners(); } Future checkIsLoggedIn() async { final result = await _authRepository.checkIsLoggedIn(); if (result is Ok) { if (result.value) { _isLoggedIn = result.value; // Restore customer data from SharedPreferences final customer = await _authRepository.getStoredCustomer(); if (customer != null) { _loggedInUser = customer; _userRole = customer.role == 'admin' ? Role.admin : Role.analyst; } } else { _isLoggedIn = false; _loggedInUser = null; _userRole = null; } } else { _isLoggedIn = false; _loggedInUser = null; _userRole = null; } notifyListeners(); } void clearAuthFlow() { _errorMessage = null; successMessage = null; usernameController.clear(); passwordController.clear(); _isLoggedIn = false; _loggedInUser = null; _userRole = null; notifyListeners(); } @override void dispose() { usernameController.dispose(); passwordController.dispose(); usernameFocus.dispose(); passwordFocus.dispose(); super.dispose(); } } enum Role { admin, analyst }