import 'package:flutter/foundation.dart'; import '../services/pin_lock_service.dart'; import '../services/settings_service.dart'; class PinLockViewModel extends ChangeNotifier { final PinLockService pinLockService; final SettingsService? settingsService; PinLockViewModel({required this.pinLockService, this.settingsService}); bool _isPinSet = false; bool _isUnlocked = false; bool _isLoading = false; bool _hasLoaded = false; bool _pinRequired = true; String? _errorMessage; bool get isPinSet => _isPinSet; bool get isUnlocked => _isUnlocked; bool get isLoading => _isLoading; bool get hasLoaded => _hasLoaded; bool get pinRequired => _pinRequired; String? get errorMessage => _errorMessage; void setPinRequired(bool value) { if (_pinRequired == value) return; _pinRequired = value; notifyListeners(); } Future ensureLoaded() async { if (_hasLoaded || _isLoading) return; await load(); } // Checks whether a pin has already been configured on this device. Future load() async { if (_isLoading) return; _isLoading = true; _errorMessage = null; notifyListeners(); try { _isPinSet = await pinLockService.hasPin(); final svc = settingsService; if (svc != null) { final settings = await svc.getSettings(); _pinRequired = settings.pinRequired; } } catch (e) { debugPrint('PinLockViewModel: load error: $e'); _errorMessage = 'Could not check PIN status.'; } finally { _hasLoaded = true; _isLoading = false; notifyListeners(); } } Future setPin(String pin) async { _errorMessage = null; try { await pinLockService.setPin(pin); _isPinSet = true; _isUnlocked = true; _pinRequired = true; final svc = settingsService; if (svc != null) { final current = await svc.getSettings(); await svc.saveSettings(current.copyWith(pinRequired: true)); } notifyListeners(); return true; } catch (e) { debugPrint('PinLockViewModel: setPin error: $e'); _errorMessage = 'Could not save PIN.'; notifyListeners(); return false; } } Future verify(String pin) async { _errorMessage = null; try { final matches = await pinLockService.verifyPin(pin); if (matches) { _isUnlocked = true; notifyListeners(); return true; } _errorMessage = 'Incorrect PIN.'; notifyListeners(); return false; } catch (e) { debugPrint('PinLockViewModel: verify error: $e'); _errorMessage = 'Could not verify PIN.'; notifyListeners(); return false; } } Future changePin({ required String currentPin, required String newPin, }) async { final currentMatches = await pinLockService.verifyPin(currentPin); if (!currentMatches) { _errorMessage = 'Current PIN is incorrect.'; notifyListeners(); return false; } return setPin(newPin); } Future disablePin(String currentPin) async { final matches = await pinLockService.verifyPin(currentPin); if (!matches) { _errorMessage = 'Current PIN is incorrect.'; notifyListeners(); return false; } await pinLockService.clearPin(); _isPinSet = false; _pinRequired = false; final svc = settingsService; if (svc != null) { final current = await svc.getSettings(); await svc.saveSettings(current.copyWith(pinRequired: false)); } notifyListeners(); return true; } void lock() { if (!_isUnlocked) return; _isUnlocked = false; notifyListeners(); } }