import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../models/office.dart'; import '../../models/profile.dart'; import '../../models/team.dart'; import '../../providers/teams_provider.dart'; import '../../providers/profile_provider.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:tasq/screens/searchable_multi_select_dropdown.dart'; import '../../widgets/tasq_adaptive_list.dart'; final officesProvider = FutureProvider>((ref) async { final data = await Supabase.instance.client.from('offices').select(); return (data as List? ?? []) .map((e) => Office.fromMap(e as Map)) .toList(); }); class TeamsScreen extends ConsumerWidget { const TeamsScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final teamsAsync = ref.watch(teamsProvider); final profilesAsync = ref.watch(profilesProvider); final officesAsync = ref.watch(officesProvider); final teamMembersAsync = ref.watch(teamMembersProvider); return Scaffold( body: teamsAsync.when( data: (teams) { final profiles = profilesAsync.valueOrNull ?? []; final offices = officesAsync.valueOrNull ?? []; final teamMembers = teamMembersAsync.valueOrNull ?? []; final profileById = {for (var p in profiles) p.id: p}; final officeById = {for (var o in offices) o.id: o}; return TasQAdaptiveList( items: teams, columns: [ TasQColumn( header: 'Name', cellBuilder: (context, team) => Text(team.name), ), TasQColumn( header: 'Leader', cellBuilder: (context, team) { final leader = profileById[team.leaderId]; return Text(leader?.fullName ?? team.leaderId); }, ), TasQColumn( header: 'Offices', cellBuilder: (context, team) { final officeNames = team.officeIds .map((id) => officeById[id]?.name ?? id) .join(', '); return Text(officeNames); }, ), TasQColumn( header: 'Members', cellBuilder: (context, team) { final members = team.members(teamMembers); final memberNames = members .map((id) => profileById[id]?.fullName ?? id) .join(', '); return Text(memberNames); }, ), ], mobileTileBuilder: (context, team, actions) { final leader = profileById[team.leaderId]; final officeNames = team.officeIds .map((id) => officeById[id]?.name ?? id) .join(', '); final members = team.members(teamMembers); final memberNames = members .map((id) => profileById[id]?.fullName ?? id) .join(', '); return ListTile( title: Text(team.name), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Leader: ${leader?.fullName ?? team.leaderId}'), Text('Offices: $officeNames'), Text('Members: $memberNames'), ], ), trailing: Row( mainAxisSize: MainAxisSize.min, children: actions, ), onTap: () => _showTeamDialog(context, ref, team: team), ); }, rowActions: (team) => [ IconButton( icon: const Icon(Icons.edit), tooltip: 'Edit', onPressed: () => _showTeamDialog(context, ref, team: team), ), IconButton( icon: const Icon(Icons.delete), tooltip: 'Delete', onPressed: () => _deleteTeam(context, ref, team.id), ), ], ); }, loading: () => const Center(child: CircularProgressIndicator()), error: (err, stack) => Center(child: Text('Error: $err')), ), floatingActionButton: FloatingActionButton( onPressed: () => _showTeamDialog(context, ref), tooltip: 'Add Team', child: const Icon(Icons.add), ), ); } void _showTeamDialog( BuildContext context, WidgetRef ref, { Team? team, }) async { final profiles = ref.read(profilesProvider).valueOrNull ?? []; final offices = await ref.read(officesProvider.future); if (!context.mounted) return; final itStaff = profiles.where((p) => p.role == 'it_staff').toList(); final nameController = TextEditingController(text: team?.name ?? ''); String? leaderId = team?.leaderId; List selectedOffices = List.from(team?.officeIds ?? []); List selectedMembers = []; final isEdit = team != null; // If editing, fetch current members if (isEdit) { final members = ref.read(teamMembersProvider).valueOrNull ?? []; selectedMembers = members .where((m) => m.teamId == team.id) .map((m) => m.userId) .toList(); } await showDialog( context: context, builder: (context) { return StatefulBuilder( builder: (context, setState) { return AlertDialog( title: Text(isEdit ? 'Edit Team' : 'Add Team'), content: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ TextField( controller: nameController, decoration: const InputDecoration(labelText: 'Team Name'), ), const SizedBox(height: 12), DropdownButtonFormField( initialValue: leaderId, items: [ for (final p in itStaff) DropdownMenuItem( value: p.id, child: Text( p.fullName.isNotEmpty ? p.fullName : p.id, ), ), ], onChanged: (v) => setState(() => leaderId = v), decoration: const InputDecoration( labelText: 'Team Leader', ), ), const SizedBox(height: 12), SearchableMultiSelectDropdown( label: 'Offices', items: offices, selectedIds: selectedOffices, getId: (o) => o.id, getLabel: (o) => o.name, onChanged: (ids) => setState(() => selectedOffices = ids), ), const SizedBox(height: 12), SearchableMultiSelectDropdown( label: 'Team Members', items: itStaff, selectedIds: selectedMembers, getId: (p) => p.id, getLabel: (p) => p.fullName.isNotEmpty ? p.fullName : p.id, onChanged: (ids) => setState(() => selectedMembers = ids), ), ], ), ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Cancel'), ), ElevatedButton( onPressed: () async { final navigator = Navigator.of(context); final name = nameController.text.trim(); if (name.isEmpty || leaderId == null) return; final client = Supabase.instance.client; if (isEdit) { await client .from('teams') .update({ 'name': name, 'leader_id': leaderId, 'office_ids': selectedOffices, }) .eq('id', team.id); // Update team members await client .from('team_members') .delete() .eq('team_id', team.id); if (selectedMembers.isNotEmpty) { await client.from('team_members').insert([ for (final userId in selectedMembers) {'team_id': team.id, 'user_id': userId}, ]); } } else { final insertRes = await client .from('teams') .insert({ 'name': name, 'leader_id': leaderId, 'office_ids': selectedOffices, }) .select() .single(); final newTeamId = insertRes['id'] as String?; if (newTeamId != null && selectedMembers.isNotEmpty) { await client.from('team_members').insert([ for (final userId in selectedMembers) {'team_id': newTeamId, 'user_id': userId}, ]); } } ref.invalidate(teamsProvider); ref.invalidate(teamMembersProvider); navigator.pop(); }, child: Text(isEdit ? 'Save' : 'Add'), ), ], ); }, ); }, ); } void _deleteTeam(BuildContext context, WidgetRef ref, String teamId) async { final navigator = Navigator.of(context); final confirmed = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Delete Team'), content: const Text('Are you sure you want to delete this team?'), actions: [ TextButton( onPressed: () => navigator.pop(false), child: const Text('Cancel'), ), ElevatedButton( onPressed: () => navigator.pop(true), child: const Text('Delete'), ), ], ), ); if (confirmed == true) { await Supabase.instance.client.from('teams').delete().eq('id', teamId); ref.invalidate(teamsProvider); } } }