import 'package:flutter/foundation.dart'; import '../models/user_profile.dart'; import '../services/api_client.dart'; import '../services/token_store.dart'; enum SessionStatus { loading, signedOut, signedIn } class SessionController extends ChangeNotifier { SessionController(this.api, this.tokens); final ApiClient api; final TokenStore tokens; SessionStatus status = SessionStatus.loading; UserProfile? user; String? organizationId; OrganizationMembership? get membership { final matches = user?.approvedMemberships.where( (item) => item.organization.id == organizationId, ); return matches == null || matches.isEmpty ? null : matches.first; } Future initialize() async { final minimumSplash = Future.delayed( const Duration(milliseconds: 1100), ); final token = await tokens.read(); if (token == null) { status = SessionStatus.signedOut; } else { try { user = await api.me(); await _selectInitialOrganization(); if (organizationId == null) { throw StateError('No approved organization membership'); } status = SessionStatus.signedIn; } catch (_) { await tokens.clear(); status = SessionStatus.signedOut; } } await minimumSplash; notifyListeners(); } Future login(String username, String password) async { final result = await api.login(username, password); await tokens.write(result.token); user = result.user; await _selectInitialOrganization(); status = SessionStatus.signedIn; notifyListeners(); } Future register(Map input) => api.register(input); Future _selectInitialOrganization() async { final approved = user?.approvedMemberships ?? const []; final saved = await tokens.readOrganization(); final selected = approved.where((item) => item.organization.id == saved); organizationId = selected.isNotEmpty ? selected.first.organization.id : (approved.isEmpty ? null : approved.first.organization.id); if (organizationId != null) { await tokens.writeOrganization(organizationId!); } } Future selectOrganization(String id) async { if (!(user?.approvedMemberships.any((item) => item.organization.id == id) ?? false)) { return; } organizationId = id; await tokens.writeOrganization(id); notifyListeners(); } Future refreshProfile() async { user = await api.me(); await _selectInitialOrganization(); notifyListeners(); } Future logout() async { await tokens.clear(); await tokens.clearOrganization(); user = null; organizationId = null; status = SessionStatus.signedOut; notifyListeners(); } Future deleteAccount(String password) async { await api.deleteAccount(password); await logout(); } }