import 'package:flutter/material.dart'; import 'package:laserscouter/core/api.dart'; import 'notespage.dart'; import 'teamadder.dart'; import 'package:to_csv/to_csv.dart' as csv_export; import 'package:shared_preferences/shared_preferences.dart'; class TeamPicker extends StatefulWidget { final String eventCode; final String eventName; final bool isCustomOnly; const TeamPicker({super.key, required this.eventCode, required this.eventName,this.isCustomOnly = false}); @override State createState() => _TeamPickerState(); } class _TeamPickerState extends State { List teamNames = []; List teamCodes = []; bool isLoading = true; String? errorMessage; @override void initState() { super.initState(); _fetchTeams(); } Future _exportData() async { List header = []; header.add('Team Number'); header.add('Bot Position'); header.add('Gen. Observations'); header.add('Auton Rundown'); header.add('Intake Position'); header.add('Can Drive Over Bump'); header.add('Can Go Under Trench'); header.add('Can Give Fuel to HP'); header.add('Climb Level'); header.add('Fuel Capacity'); header.add('Fuel per Cycle'); header.add("Cycle Time"); List> data = []; for (int i = 0; i < teamCodes.length; i++) { String generateKey(String field) { return '${teamCodes[i]}_${widget.eventCode}_$field'; } SharedPreferences prefs = await SharedPreferences.getInstance(); String? botPosition = prefs.getString(generateKey('botPosition')); String? generalObservations = prefs.getString(generateKey('generalObservations')); String? autonRundown = prefs.getString(generateKey('autonRundown')); String? intakePosition = prefs.getString(generateKey('intakePosition')); String? canDriveOverBump = prefs.getBool(generateKey('canDriveOverBump')).toString(); String? canDriveUnderTrench = prefs.getBool(generateKey('canDriveUnderTrench')).toString(); String? canGiveToHumanPlayer = prefs.getBool(generateKey('canGiveToHumanPlayer')).toString(); String? climbLevel = prefs.getDouble(generateKey('climbLevel')).toString(); String? fuelCapacity = prefs.getDouble(generateKey('fuelCapacity')).toString(); String? fuelPerCycle = prefs.getDouble(generateKey('fuelPerCycle')).toString(); String? cycleTime = prefs.getDouble(generateKey('cycleTime')).toString(); if (canDriveOverBump == 'null') { canDriveOverBump = ''; } if (canDriveUnderTrench == 'null') { canDriveUnderTrench = ''; } if (canGiveToHumanPlayer == 'null') { canGiveToHumanPlayer = ''; } if (climbLevel == 'null') { climbLevel = ''; } if (fuelCapacity == 'null') { fuelCapacity = ''; } if (fuelPerCycle == 'null') { fuelPerCycle = ''; } if (cycleTime == 'null') { cycleTime = ''; } List teamData = []; teamData.add(teamCodes[i]); teamData.add(botPosition ?? ''); teamData.add(generalObservations ?? ''); teamData.add(autonRundown ?? ''); teamData.add(intakePosition ?? ''); teamData.add(canDriveOverBump); teamData.add(canDriveUnderTrench); teamData.add(canGiveToHumanPlayer); teamData.add(climbLevel); teamData.add(fuelCapacity); teamData.add(fuelPerCycle); teamData.add(cycleTime); data.add(teamData); } csv_export.myCSV(header, data, setHeadersInFirstRow: true, fileName: 'laserscouter_${widget.eventCode}.csv'); } Future _fetchTeams() async { try { List apiTeamNames = []; List apiTeamCodes = []; if (!widget.isCustomOnly) { final EventSearchResult apiResult = await eventSearch(widget.eventCode); apiTeamNames = apiResult.teamNames; apiTeamCodes = apiResult.teamCodes; } final SharedPreferences prefs = await SharedPreferences.getInstance(); final List customTeamNames = prefs.getStringList('custom_team_names_${widget.eventName}') ?? []; final List customTeamCodes = prefs.getStringList('custom_team_numbers_${widget.eventCode}') ?? []; List combinedNames = []; List combinedCodes = []; for (int i = 0; i < apiTeamCodes.length; i++) { if (!combinedCodes.contains(apiTeamCodes[i])) { combinedCodes.add(apiTeamCodes[i]); if (i < apiTeamNames.length) { combinedNames.add(apiTeamNames[i]); } else { combinedNames.add(''); } } } for (int i = 0; i < customTeamCodes.length; i++) { if (!combinedCodes.contains(customTeamCodes[i])) { combinedCodes.add(customTeamCodes[i]); if (i < customTeamNames.length) { combinedNames.add(customTeamNames[i]); } else { combinedNames.add(''); } } } if (mounted) { setState(() { teamNames = combinedNames.toList(); teamCodes = combinedCodes.toList(); isLoading = false; }); } } catch (e) { if (mounted) { setState(() { errorMessage = widget.isCustomOnly ? "Could not load custom teams." : "Failed to load teams. Please try again."; isLoading = false; }); } } } Future _refreshTeams() async { setState(() { isLoading = true; }); await _fetchTeams(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Teams'), actions: [ IconButton( onPressed: () async { await Navigator.push( context, MaterialPageRoute( builder: (context) => TeamAdder(eventCode: widget.eventCode,), ), ); _refreshTeams(); }, icon: Icon(Icons.add), ) ] ), body: _buildBody(), floatingActionButton: FloatingActionButton( onPressed: _exportData, child: const Icon(Icons.share), ), ); } Widget _buildBody() { if (isLoading) { return const Center(child: CircularProgressIndicator()); } if (errorMessage != null) { return Center( child: Padding( padding: const EdgeInsets.all(16.0), child: Text( errorMessage!, textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyLarge?.copyWith( color: Colors.red, ), ), ), ); } if (teamCodes.isEmpty) { return const Center( child: Text('No teams found for this event.'), ); } return ListView.builder( itemCount: teamCodes.length, itemBuilder: (context, index) { return ListTile( title: Text('${teamCodes[index]} - ${teamNames[index]}'), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => NotesPage( teamName: teamNames[index], eventCode: widget.eventCode, teamCode: teamCodes[index], ), ), ); }, ); }, ); } }