import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; import 'package:pshared/config/constants.dart'; import 'package:pshared/models/organization/organization.dart'; import 'package:pshared/provider/resource.dart'; import 'package:pshared/service/organization.dart'; import 'package:pshared/service/secure_storage.dart'; import 'package:pshared/utils/exception.dart'; class OrganizationsProvider extends ChangeNotifier { Resource> _resource = Resource(data: []); Resource> get resource => _resource; List get organizations => _resource.data ?? []; String? _currentOrg; Organization get current => isOrganizationSet ? _current! : throw StateError('Organization is not set'); Organization? _org(String? orgRef) => organizations.firstWhereOrNull((org) => org.id == orgRef); Organization? get _current => _org(_currentOrg); bool get isOrganizationSet => _current != null; bool get isLoading => _resource.isLoading; Object? get error => _resource.error; void _setResource(Resource> newResource) { _resource = newResource; notifyListeners(); } Future> load() async { _setResource(_resource.copyWith(isLoading: true, error: null)); try { final orgs = await OrganizationService.list(); // keep fetched organizations so _org can resolve against them _setResource(Resource(data: orgs, isLoading: true)); // fetch stored org String? org = await SecureStorageService.get(Constants.currentOrgKey); // check stored org availability org = orgs.firstWhereOrNull((o) => o.id == org)?.id; // fallback if org is not set or not available org ??= orgs.first.id; await setCurrentOrganization(org); _setResource(Resource(data: orgs, isLoading: false)); return orgs; } catch (e) { _setResource(_resource.copyWith(isLoading: false, error: toException(e))); rethrow; } } Future loadByInvitation(String invitationRef) async { _setResource(_resource.copyWith(isLoading: true, error: null)); try { final org = await OrganizationService.loadByInvitation(invitationRef); _setResource(Resource(data: [org], isLoading: true)); await setCurrentOrganization(org.id); _setResource(Resource(data: [org], isLoading: false)); return org; } catch (e) { _setResource(_resource.copyWith(isLoading: false, error: toException(e))); rethrow; } } bool _setCurrentOrganization(String? orgRef) { final organizationRef = _org(orgRef)?.id; if (organizationRef == null) return false; _currentOrg = organizationRef; return true; } Future setCurrentOrganization(String? orgRef) async { if (!_setCurrentOrganization(orgRef)) return false; await SecureStorageService.set(Constants.currentOrgKey, orgRef); notifyListeners(); return true; } Future reset() async { _resource = Resource(data: []); _currentOrg = null; notifyListeners(); // Best-effort cleanup of stored selection to avoid using stale org on next login. await SecureStorageService.delete(Constants.currentOrgKey); } }