import 'package:flux/core/enums_and_consts/consts.dart'; import 'package:flux/features/master_data/staff/models/staff_member_model.dart'; import 'package:flux/features/master_data/store/models/store_model.dart'; import 'package:get_it/get_it.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; class StaffRepository { final SupabaseClient _supabase = GetIt.I.get(); // --- ANAGRAFICA PURA --- // Prende tutto lo staff della Company (per l'Hub Anagrafiche) Future> getStaffMembers(String companyId) async { final response = await _supabase .from(Tables.staffMembers) .select(''' *, stores (*) ''') .eq('company_id', companyId) .order('name', ascending: true); return (response as List).map((s) => StaffMemberModel.fromMap(s)).toList(); } Future getStaffMemberById(String staffId) async { try { final response = await _supabase .from(Tables.staffMembers) .select() .eq('id', staffId) .single(); return StaffMemberModel.fromMap(response); } on Exception catch (e) { throw ('Errore nel recupero del membro staff con ID $staffId: $e'); } } Future saveStaffMember(StaffMemberModel member) async { final response = await _supabase .from(Tables.staffMembers) .upsert(member.toMap()) .select() .single(); return StaffMemberModel.fromMap(response); } // --- LOGICA DI INVITO (Tramite Edge Function) --- Future inviteStaffMember(StaffMemberModel newMember) async { if (newMember.email == null || newMember.email!.isEmpty) { throw Exception( "L'indirizzo email รจ obbligatorio per invitare un collega.", ); } try { final response = await _supabase.functions.invoke( 'invite_staff', body: newMember.toMap(), ); if (response.status != 200) { throw Exception("Errore dal server: ${response.data}"); } // La funzione ci restituisce l'ID fresco di database! final responseData = response.data as Map; return responseData['user_id'] as String; } on FunctionException catch (e) { throw Exception( "Errore di comunicazione con il server: ${e.reasonPhrase}", ); } catch (e) { throw Exception("Impossibile invitare il collega: $e"); } } Future resetPasswordOrResendInviteLink(String email) async { try { await _supabase.auth.resetPasswordForEmail( email, redirectTo: resetPasswordUrl, ); } catch (e) { throw Exception("Errore nell'invio del link: $e"); } } // --- LOGICA DI GIUNZIONE (Staff <-> Store) --- // Recupera i membri assegnati a uno specifico negozio // Qui facciamo una JOIN per avere i dati del membro partendo dalla tabella di giunzione Future> getStaffMembersInStore(String storeId) async { final response = await _supabase .from(Tables.staffInStores) .select( '${Tables.staffMembers} (*)', ) // Prende tutti i campi della tabella staff_member collegata .eq('store_id', storeId); return (response as List) .map((item) => StaffMemberModel.fromMap(item[Tables.staffMembers])) .toList(); } // Recupera i negozi assegnati a uno specifico membro // Qui facciamo una JOIN per avere i dati del membro partendo dalla tabella di giunzione Future> getStaffMemberStore(String staffId) async { final response = await _supabase .from(Tables.staffInStores) .select( '${Tables.stores} (*)', ) // Prende tutti i campi della tabella store collegata .eq('staff_member_id', staffId); return (response as List) .map((item) => StoreModel.fromMap(item[Tables.stores])) .toList(); } // Assegna un membro a un negozio Future assignStaffToStore(String staffId, String storeId) async { await _supabase.from(Tables.staffInStores).insert({ 'staff_member_id': staffId, 'store_id': storeId, }); } // Rimuove l'assegnazione Future removeStaffFromStore(String staffId, String storeId) async { await _supabase .from(Tables.staffInStores) .delete() .eq('staff_member_id', staffId) .eq('store_id', storeId); } // Nel StaffRepository // Utility per pulire le assegnazioni esistenti prima di riscriverle Future clearStoreAssignments(String staffId) async { await _supabase .from(Tables.staffInStores) .delete() .eq('staff_member_id', staffId); } }