import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:shared_preferences/shared_preferences.dart'; import '../../globals.dart'; class JoinMatchPage extends StatefulWidget { @override _JoinMatchPageState createState() => _JoinMatchPageState(); } class _JoinMatchPageState extends State { TextEditingController _matchIdController = TextEditingController(); bool _isJoined = false; bool _isLoading = false; bool _is2v2Mode = false; int _selectedSlot = 2; int _player1Score = 0; int _player2Score = 0; int _player3Score = 0; int _player4Score = 0; String? _matchId; String? _player1name; String? _player2name; List _players = []; bool _canEdit = false; final String _joinMatchApiUrl = '$apiurl/joinmatch'; final String _joinMatch2v2ApiUrl = '$apiurl/joinmatch_2v2'; final String _endMatchApiUrl = '$apiurl/endmatch'; final String _endFourApiUrl = '$apiurl/endfour'; Future _joinMatch() async { setState(() { _isLoading = true; }); final prefs = await SharedPreferences.getInstance(); final String? token = prefs.getString('token'); final String matchId = _matchIdController.text; if (token == null) { _showToast('No token found. Please login again.'); setState(() { _isLoading = false; }); return; } try { if (_is2v2Mode) { // Joining a 2v2 match final response = await http.post( Uri.parse(_joinMatch2v2ApiUrl), headers: {'Content-Type': 'application/json'}, body: json.encode({ 'token': token, 'match_id': int.parse(matchId), 'slot': _selectedSlot, }), ); if (response.statusCode == 200) { final responseData = json.decode(response.body); setState(() { _isJoined = true; _matchId = matchId; _players = List.from( responseData['players'].map((p) => p['name'])); _canEdit = responseData['canEdit']; _player1Score = 0; _player2Score = 0; _player3Score = 0; _player4Score = 0; }); _showToast('Joined match successfully!'); } else { _showToast('Failed to join 2v2 match.'); } } else { // Joining a 1v1 match final response = await http.post( Uri.parse(_joinMatchApiUrl), headers: {'Content-Type': 'application/json'}, body: json.encode({ 'token': token, 'match_id': int.parse(matchId), }), ); if (response.statusCode == 200) { final responseData = json.decode(response.body); setState(() { _isJoined = true; _player1name = responseData['player1_name']; _player2name = responseData['player2_name']; _player1Score = 0; _player2Score = 0; _matchId = matchId; }); _showToast('Joined match successfully!'); } else { _showToast('Failed to join match.'); } } } catch (e) { _showToast('Error: $e'); } finally { setState(() { _isLoading = false; }); } } Future _endMatch() async { setState(() { _isLoading = true; }); final prefs = await SharedPreferences.getInstance(); final String? token = prefs.getString('token'); if (token == null) { _showToast('No token found. Please login again.'); setState(() { _isLoading = false; }); return; } try { if (_is2v2Mode) { // End the 2v2 match using the /endfour API final response = await http.post( Uri.parse(_endFourApiUrl), headers: {'Content-Type': 'application/json'}, body: json.encode({ 'match_id': int.parse(_matchId!), 'player1_team1_score': _player1Score, 'player2_team1_score': _player2Score, 'player1_team2_score': _player3Score, 'player2_team2_score': _player4Score, }), ); if (response.statusCode == 200) { _showToast('2v2 match ended successfully!'); } else { _showToast('Failed to end 2v2 match.'); } } else { // End the 1v1 match final response = await http.post( Uri.parse(_endMatchApiUrl), headers: {'Content-Type': 'application/json'}, body: json.encode({ 'match_id': int.parse(_matchId!), 'player1_score': _player1Score, 'player2_score': _player2Score, }), ); if (response.statusCode == 200) { _showToast('Match ended successfully!'); } else { _showToast('Failed to end match.'); } } } catch (e) { _showToast('Error: $e'); } finally { setState(() { _isLoading = false; }); } } void _showToast(String message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(message)), ); } @override Widget build(BuildContext context) { return Scaffold( body: Padding( padding: const EdgeInsets.all(16.0), child: _isLoading ? Center(child: CircularProgressIndicator()) : _isJoined ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // Display for 2v2 match if (_is2v2Mode && _canEdit) ...[ Text('2v2 Match', style: TextStyle(color: Colors.white, fontSize: 24)), SizedBox(height: 16), // First Team Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Column( children: [ Text(_players[0], style: TextStyle(color: Colors.white)), Row( children: [ IconButton( icon: Icon(Icons.remove, color: Colors.white), onPressed: () => _updateScore(1, -1)), Container( width: 100, height: 50, decoration: BoxDecoration( border: Border.all( color: Colors.white, width: 2), borderRadius: BorderRadius.circular(8)), child: Center( child: Text('$_player1Score', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 24)))), IconButton( icon: Icon(Icons.add, color: Colors.white), onPressed: () => _updateScore(1, 1)), ], ), ], ), SizedBox(width: 32), Column( children: [ Text(_players[1], style: TextStyle(color: Colors.white)), Row( children: [ IconButton( icon: Icon(Icons.remove, color: Colors.white), onPressed: () => _updateScore(2, -1)), Container( width: 100, height: 50, decoration: BoxDecoration( border: Border.all( color: Colors.white, width: 2), borderRadius: BorderRadius.circular(8)), child: Center( child: Text('$_player2Score', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 24)))), IconButton( icon: Icon(Icons.add, color: Colors.white), onPressed: () => _updateScore(2, 1)), ], ), ], ), ], ), SizedBox(height: 32), // Second Team Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Column( children: [ Text(_players[2], style: TextStyle(color: Colors.white)), Row( children: [ IconButton( icon: Icon(Icons.remove, color: Colors.white), onPressed: () => _updateScore(3, -1)), Container( width: 100, height: 50, decoration: BoxDecoration( border: Border.all( color: Colors.white, width: 2), borderRadius: BorderRadius.circular(8)), child: Center( child: Text('$_player3Score', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 24)))), IconButton( icon: Icon(Icons.add, color: Colors.white), onPressed: () => _updateScore(3, 1)), ], ), ], ), SizedBox(width: 32), Column( children: [ Text(_players[3], style: TextStyle(color: Colors.white)), Row( children: [ IconButton( icon: Icon(Icons.remove, color: Colors.white), onPressed: () => _updateScore(4, -1)), Container( width: 100, height: 50, decoration: BoxDecoration( border: Border.all( color: Colors.white, width: 2), borderRadius: BorderRadius.circular(8)), child: Center( child: Text('$_player4Score', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 24)))), IconButton( icon: Icon(Icons.add, color: Colors.white), onPressed: () => _updateScore(4, 1)), ], ), ], ), ], ), ], // 1v1 Match UI if (!_is2v2Mode) ...[ Text(_player1name ?? 'Player 1', style: TextStyle(color: Colors.white)), SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ IconButton( icon: Icon(Icons.remove, color: Colors.white), onPressed: () => _updateScore(1, -1)), Container( width: 100, height: 50, decoration: BoxDecoration( border: Border.all( color: Colors.white, width: 2), borderRadius: BorderRadius.circular(8)), child: Center( child: Text('$_player1Score', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 24)))), IconButton( icon: Icon(Icons.add, color: Colors.white), onPressed: () => _updateScore(1, 1)), ], ), SizedBox(height: 8), Divider( color: Colors.white, thickness: 2, indent: 80, endIndent: 80), SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ IconButton( icon: Icon(Icons.remove, color: Colors.white), onPressed: () => _updateScore(2, -1)), Container( width: 100, height: 50, decoration: BoxDecoration( border: Border.all( color: Colors.white, width: 2), borderRadius: BorderRadius.circular(8)), child: Center( child: Text('$_player2Score', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 24)))), IconButton( icon: Icon(Icons.add, color: Colors.white), onPressed: () => _updateScore(2, 1)), ], ), SizedBox(height: 8), Text(_player2name ?? 'Player 2', style: TextStyle(color: Colors.white)), ], SizedBox(height: 32), ElevatedButton( onPressed: _endMatch, child: Text('End Match'), ), ], ), ) : Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ // Match ID Text Field TextField( controller: _matchIdController, decoration: InputDecoration( labelText: 'Enter Match ID', border: OutlineInputBorder(), ), ), SizedBox(height: 16), // Toggle for 2v2 Mode SwitchListTile( title: Text('Enable 2v2 Mode'), value: _is2v2Mode, onChanged: (value) { setState(() { _is2v2Mode = value; }); }, ), // If 2v2 is selected, display slot selection if (_is2v2Mode) ...[ DropdownButton( value: _selectedSlot, items: [2, 3, 4].map((int value) { return DropdownMenuItem( value: value, child: Text('Slot $value'), ); }).toList(), onChanged: (int? newValue) { setState(() { _selectedSlot = newValue!; }); }, ), ], SizedBox(height: 16), ElevatedButton( onPressed: () { if (_matchIdController.text.isNotEmpty) { _joinMatch(); } else { _showToast('Please enter a Match ID.'); } }, child: Text('Join Match'), ), ], ), ), ); } void _updateScore(int playerIndex, int increment) { setState(() { if (playerIndex == 1) { _player1Score += increment; } else if (playerIndex == 2) { _player2Score += increment; } else if (playerIndex == 3) { _player3Score += increment; } else if (playerIndex == 4) { _player4Score += increment; } }); } }