import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../../core/utils/table_search.dart'; import '../../domain/entities/rbac_entities.dart'; enum RbacTab { users, roles, permissions } class RbacState { const RbacState({ this.users = const [], this.roles = const [], this.selectedTab = RbacTab.users, this.selectedRoleId = 'super_admin', this.searchQuery = '', this.roleFilter = 'All Roles', this.departmentFilter = 'All Departments', this.statusFilter = 'All Statuses', this.currentPage = 0, this.pageSize = 10, }); final List users; final List roles; final RbacTab selectedTab; final String selectedRoleId; final String searchQuery; final String roleFilter; final String departmentFilter; final String statusFilter; final int currentPage; final int pageSize; int get totalUsers => users.length; int get activeUsers => users.where((u) => u.status == UserAccountStatus.active).length; int get inactiveUsers => users.where((u) => u.status == UserAccountStatus.inactive).length; int get lockedUsers => users.where((u) => u.status == UserAccountStatus.locked).length; List get filteredUsers { return users.where((user) { final q = searchQuery.toLowerCase(); final matchesSearch = q.isEmpty || user.name.toLowerCase().contains(q) || user.email.toLowerCase().contains(q) || user.employeeCode.toLowerCase().contains(q); final matchesRole = roleFilter == 'All Roles' || user.roleName == roleFilter; final matchesDept = departmentFilter == 'All Departments' || user.department == departmentFilter; final matchesStatus = statusFilter == 'All Statuses' || user.status.label == statusFilter; return matchesSearch && matchesRole && matchesDept && matchesStatus; }).toList(); } List get pagedUsers { final filtered = filteredUsers; final start = currentPage * pageSize; if (start >= filtered.length) return []; final end = (start + pageSize).clamp(0, filtered.length); return filtered.sublist(start, end); } int get totalPages => (filteredUsers.length / pageSize).ceil().clamp(1, 999); ManagedRole? get selectedRole { for (final role in roles) { if (role.id == selectedRoleId) return role; } return roles.isNotEmpty ? roles.first : null; } RbacState copyWith({ List? users, List? roles, RbacTab? selectedTab, String? selectedRoleId, String? searchQuery, String? roleFilter, String? departmentFilter, String? statusFilter, int? currentPage, int? pageSize, }) { return RbacState( users: users ?? this.users, roles: roles ?? this.roles, selectedTab: selectedTab ?? this.selectedTab, selectedRoleId: selectedRoleId ?? this.selectedRoleId, searchQuery: searchQuery ?? this.searchQuery, roleFilter: roleFilter ?? this.roleFilter, departmentFilter: departmentFilter ?? this.departmentFilter, statusFilter: statusFilter ?? this.statusFilter, currentPage: currentPage ?? this.currentPage, pageSize: pageSize ?? this.pageSize, ); } } final rbacProvider = StateNotifierProvider((ref) { return RbacNotifier(); }); class RbacNotifier extends StateNotifier { RbacNotifier() : super(RbacState( users: List.of(defaultUsers), roles: List.of(defaultRoles), )) { _recountRoleUsers(); } void setTab(RbacTab tab) => state = state.copyWith(selectedTab: tab, currentPage: 0); void setSearch(String query) => state = state.copyWith(searchQuery: TableSearch.normalize(query), currentPage: 0); void setRoleFilter(String filter) => state = state.copyWith(roleFilter: filter, currentPage: 0); void setDepartmentFilter(String filter) => state = state.copyWith(departmentFilter: filter, currentPage: 0); void setStatusFilter(String filter) => state = state.copyWith(statusFilter: filter, currentPage: 0); void setPage(int page) => state = state.copyWith(currentPage: page); void selectRole(String roleId) => state = state.copyWith(selectedRoleId: roleId); void togglePermission(String module, RbacAction action) { final role = state.selectedRole; if (role == null) return; final key = permissionKey(module, action); final updated = Set.from(role.permissions); if (updated.contains(key)) { updated.remove(key); } else { updated.add(key); } final roles = state.roles.map((r) { if (r.id == role.id) return r.copyWith(permissions: updated); return r; }).toList(); state = state.copyWith(roles: roles); } void savePermissions() { // Permissions already in state; would sync to API here. } void addUser(ManagedUser user) { state = state.copyWith(users: [...state.users, user]); _recountRoleUsers(); } void addRole(ManagedRole role) { state = state.copyWith( roles: [...state.roles, role], selectedRoleId: role.id, ); } void deleteRole(String roleId) { if (roleId == 'super_admin') return; state = state.copyWith( roles: state.roles.where((r) => r.id != roleId).toList(), ); _recountRoleUsers(); } void _recountRoleUsers() { final roles = state.roles.map((role) { final count = state.users.where((u) => u.roleId == role.id).length; return role.copyWith(userCount: count); }).toList(); state = state.copyWith(roles: roles); } }