public class TeamRostersGUI extends JFrame {

    private JPanel mainPanel;
    private FootballTeamRostersPage teamRostersPage;
    private Map<String, Integer> teamStandings;  // Map to store team standings

    public TeamRostersGUI() {
        setTitle("Football Team Rosters Generator");
        setSize(1000, 1000);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        mainPanel = new JPanel(new CardLayout());
        teamRostersPage = new FootballTeamRostersPage();

        mainPanel.add(createCoverPage(), "cover");
        mainPanel.add(teamRostersPage, "teamRosters");

        getContentPane().add(mainPanel, BorderLayout.CENTER);
    }

    private JPanel createCoverPage() {
        JPanel coverPanel = new JPanel(new BorderLayout());

        // Set a nostalgic retro background image (replace with your image file)
        ImageIcon backgroundImage = new ImageIcon("C:\\Users\\Vusum\\OneDrive\\Documents\\13774adb-2bfa-4582-8253-d21f4c4b7944_clipdrop-enhance.jpg");
        JLabel backgroundLabel = new JLabel(backgroundImage);
        coverPanel.add(backgroundLabel, BorderLayout.CENTER);

        // Create a "Start" button
        JButton startButton = new JButton("Start");
        startButton.setFont(new Font("Arial", Font.BOLD, 24));
        startButton.setForeground(Color.RED);
        startButton.setPreferredSize(new Dimension(200, 60));
        startButton.addActionListener(e -> showTeamRostersPage());

        JPanel buttonPanel = new JPanel();
        buttonPanel.setOpaque(false);
        buttonPanel.add(startButton);

        coverPanel.add(buttonPanel, BorderLayout.SOUTH);

        return coverPanel;
    }

    private void showTeamRostersPage() {
        ((CardLayout) mainPanel.getLayout()).show(mainPanel, "teamRosters");
        teamRostersPage.loadTeamsFromFile("C:\\Users\\Vusum\\OneDrive\\Documents\\teams.txt");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
                e.printStackTrace();
            }

            TeamRostersGUI app = new TeamRostersGUI();
            app.setVisible(true);
        });
    }
}

class FootballTeamRostersPage extends JPanel {

    private List<Team> teams;
    List<Team> updatedTeams;
    private List<Player> players;
    private Map<String, List<Player>> teamRosters;
    private JTextArea rosterTextArea;
    private JTextArea unpickedPlayersTextArea;
    private JButton generateButton;
    private JButton transferMarketButton;
    private JButton viewTeamButton;
    private JTextArea transferMarketTextArea;
    private JPanel managerCareerPanel = null;
    private JButton managerCareerButton;
    private JTextField searchField;
    private JButton searchButton;

    public FootballTeamRostersPage() {
        setBackground(new Color(0, 102, 204));
        setLayout(null);

        teamStandings = new HashMap<>();
        teamRosters = new HashMap<>();
        players = new ArrayList<>();
        rosterTextArea = new JTextArea(20, 40);
        rosterTextArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(rosterTextArea);
        scrollPane.setBounds(50, 50, 300, 400);

        unpickedPlayersTextArea = new JTextArea(20, 40);
        unpickedPlayersTextArea.setEditable(false);
        JScrollPane unpickedScrollPane = new JScrollPane(unpickedPlayersTextArea);
        unpickedScrollPane.setBounds(50, 530, 300, 200);

        generateButton = new JButton("Generate Rosters");
        generateButton.setBounds(50, 480, 200, 40);
        generateButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                loadPlayersFromFile("C:\\Users\\Vusum\\OneDrive\\Documents\\Players17.txt");
                generateRosters();
                displayRosters();
            }
        });

        transferMarketButton = new JButton("Transfer Market");
        transferMarketButton.setBounds(270, 480, 200, 40);
        transferMarketButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                openTransferMarket();
            }
        });

        viewTeamButton = new JButton("View Team");
        viewTeamButton.setBounds(490, 480, 200, 40);
        viewTeamButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                openViewTeam();
            }
        });

        transferMarketTextArea = new JTextArea(20, 40);
        transferMarketTextArea.setEditable(false);
        JScrollPane transferMarketScrollPane = new JScrollPane(transferMarketTextArea);
        transferMarketScrollPane.setBounds(400, 50, 300, 400);

        add(scrollPane);
        add(unpickedScrollPane);
        add(generateButton);
        add(transferMarketButton);
        add(viewTeamButton);
        add(transferMarketScrollPane);

        JButton simulateButton = new JButton("Simulate Season");
        simulateButton.addActionListener(e -> simulateSeason());

        add(simulateButton);
        simulateButton.setBounds(50, 450, 200, 40);
        revalidate();
        repaint();

    }

    public Map<String, Integer> teamStandings;

    private void showTeamRosters() {
        // Switch back to the team rosters page
        ((CardLayout) getParent().getLayout()).show(getParent(), "teamRosters");
    }

    public void loadTeamsFromFile(String filename) {
        teams = new ArrayList<>();
        try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
            String line;
            while ((line = br.readLine()) != null) {
                String[] parts = line.split(":");
                if (parts.length == 3) {
                    String teamName = parts[0].trim();
                    double transferBudget = Double.parseDouble(parts[1].trim().replace("m", ""));
                    String formation = parts[2].trim();
                    Team team = new Team(teamName, transferBudget, formation);
                    teams.add(team);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void loadPlayersFromFile(String filename) {
        players.clear();
        try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
            String line;
            while ((line = br.readLine()) != null) {
                // Split using tab as the delimiter
                String[] parts = line.split("\t");
                if (parts.length == 4) {
                    String playerName = parts[0].trim();
                    String playerPosition = parts[1].trim();
                    // Assuming transfer price is in millions
                    int transferPrice = (int) Double.parseDouble(parts[3].trim().replace("m", ""));
                    int rating = Integer.parseInt(parts[2].trim());
                    Player player = new Player(playerName, playerPosition, transferPrice, rating, null);
                    player.setFreeAgent(true); // Mark as free agent initially

                    players.add(player);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void generateRosters() {
        // Clear previous roster information
        teamRosters.clear();
        List<Player> unpickedPlayers = new ArrayList<>(players);

        for (Team team : teams) {
            List<Player> roster = new ArrayList<>();
            boolean hasGK = false; // Flag to track if the team already has a goalkeeper

            // Fill the roster with random players, ensuring only one goalkeeper
            for (int i = 0; i < 17; i++) { // Maximum 17 players per team (16 outfield + 1 GK)
                if (!unpickedPlayers.isEmpty()) {
                    int index = new Random().nextInt(unpickedPlayers.size());
                    Player player = unpickedPlayers.get(index);

                    if (player.getPosition().equalsIgnoreCase("GK") && hasGK) {
                        // Skip adding another goalkeeper
                        continue;
                    }

                    if (player.getPosition().equalsIgnoreCase("GK")) {
                        hasGK = true;
                    }

                    // Track the previous club for transferred players
                    if (!team.getName().equals(player.getPreviousClub())) {
                        player.setPreviousClub(team.getName());
                        player.setTransferStatus("Transferred");
                    } else {
                        player.setTransferStatus("Free Agent");
                    }

                    roster.add(player);
                    player.setFreeAgent(false); // No longer a free agent
                    unpickedPlayers.remove(player);

                } else {
                    break; // No more players to pick from
                }
            }

            teamRosters.put(team.getName(), roster);
        }
        for (Team team : teams) {
            List<Player> roster = teamRosters.get(team.getName());
            if (roster != null) {
                for (Player player : roster) {
                    player.setPicked(true);
                }
            }
        }

        // Display unpicked players
        displayUnpickedPlayers(unpickedPlayers);
    }

    public void displayRosters() {
        JPanel rosterPanel = new JPanel(new GridLayout(teams.size(), 1, 10, 10)); // Rows for each team
        rosterPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        for (Map.Entry<String, List<Player>> entry : teamRosters.entrySet()) {
            String teamName = entry.getKey();
            List<Player> roster = entry.getValue();

            JPanel teamRosterPanel = new JPanel(new GridLayout(6, 5)); // 6 rows x 5 columns for player info
            teamRosterPanel.setBorder(BorderFactory.createTitledBorder(teamName));

            for (Player player : roster) {
                JPanel playerPanel = new JPanel(new GridLayout(3, 1)); // 3 rows for name, position, and rating
                playerPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

                JLabel nameLabel = new JLabel(player.getName());
                nameLabel.setHorizontalAlignment(SwingConstants.CENTER);

                JLabel positionLabel = new JLabel("Position: " + player.getPosition());
                positionLabel.setHorizontalAlignment(SwingConstants.CENTER);

                JLabel ratingLabel = new JLabel("Rating: " + player.getRating());
                ratingLabel.setHorizontalAlignment(SwingConstants.CENTER);

                playerPanel.add(nameLabel);
                playerPanel.add(positionLabel);
                playerPanel.add(ratingLabel);

                teamRosterPanel.add(playerPanel);
            }

            rosterPanel.add(teamRosterPanel);
        }

        JScrollPane rosterScrollPane = new JScrollPane(rosterPanel);
        rosterTextArea.setText(""); // Clear the old text
        rosterTextArea.setLayout(new BorderLayout());
        rosterTextArea.add(rosterScrollPane, BorderLayout.CENTER);
    }

    public void displayUnpickedPlayers(List<Player> unpickedPlayers) {
        StringBuilder unpickedPlayersBuilder = new StringBuilder("Unpicked Players:\n");

        for (Player player : unpickedPlayers) {
            if (!player.isPicked()) {
                unpickedPlayersBuilder.append(player.getName()).append(" (")
                        .append(player.getPosition()).append("), Rating: ").append(player.getRating());
            }
            // Display transfer status and previous club for realism
            String transferStatus = player.getTransferStatus();
            String previousClub = player.getPreviousClub();
            if (transferStatus != null) {
                unpickedPlayersBuilder.append(", Transfer Status: ").append(transferStatus);
                if (transferStatus.equals("Transferred") && previousClub != null) {
                    unpickedPlayersBuilder.append(", Previous Club: ").append(previousClub);
                }
            }

            unpickedPlayersBuilder.append("\n");
        }

        unpickedPlayersTextArea.setText(unpickedPlayersBuilder.toString());
    }

    public void openTransferMarket() {
        JFrame transferMarketFrame = new JFrame("Transfer Market");
        transferMarketFrame.setSize(800, 600);
        transferMarketFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        transferMarketFrame.setLocationRelativeTo(this);

        JPanel transferMarketPanel = new JPanel();
        transferMarketPanel.setLayout(new BorderLayout());

        JTextArea transferMarketTextArea = new JTextArea(20, 40);
        transferMarketTextArea.setEditable(false);
        JScrollPane transferMarketScrollPane = new JScrollPane(transferMarketTextArea);
        transferMarketPanel.add(transferMarketScrollPane, BorderLayout.CENTER);

        // Add a "Simulate Transfer Window" button
        JButton simulateButton = new JButton("Simulate Transfer Window");
        simulateButton.setBounds(50, 480, 200, 40);
        simulateButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                simulateTransferWindow(transferMarketTextArea);
            }
        });
        transferMarketPanel.add(simulateButton, BorderLayout.SOUTH);

        transferMarketFrame.add(transferMarketPanel);
        transferMarketFrame.setVisible(true);
    }

    public void simulateTransferWindow(JTextArea transferMarketTextArea) {

        List<Player> availablePlayers = new ArrayList<>(players);
        // Define transfer window parameters
        int transferWindowHours = 20; // Total transfer window duration (hours)
        int maxTransfersPerHour = 8; // Maximum transfers per hour
        int transferDeadlineHour = 20; // Hour at which the transfer window closes

        // Track transferred players and their destinations
        Map<Player, Team> transferHistory = new HashMap<>();
        Map<Player, Team> freeAgentTransfers = new HashMap<>();
        Map<Team, List<Player>> playersBought = new HashMap<>();
        Map<Team, Double> moneySpent = new HashMap<>();

        for (int hour = 1; hour <= transferWindowHours; hour++) {
            if (hour <= transferDeadlineHour) {
                // Simulate negotiations and transfers within the transfer window
                int negotiationsThisHour = new Random().nextInt(maxTransfersPerHour + 1); // Randomize negotiations per hour

                for (int i = 0; i < negotiationsThisHour; i++) {
                    if (!players.isEmpty() && !teams.isEmpty()) {
                        int randomPlayerIndex = new Random().nextInt(availablePlayers.size());
                        Player playerToTransfer = availablePlayers.get(randomPlayerIndex);
                        availablePlayers.remove(randomPlayerIndex);

                        int randomTeamIndex = new Random().nextInt(teams.size());
                        Team destinationTeam = teams.get(randomTeamIndex);

                        if (playerToTransfer.getTransferPrice() <= destinationTeam.getTransferBudget()) {
                            // Simulate negotiation for transfer fee
                            int negotiatedFee = simulateNegotiation(playerToTransfer.getTransferPrice());

                            if (negotiatedFee > 0) {
                                // Transfer fee paid from the destination team's budget
                                destinationTeam.deductTransferBudget(negotiatedFee);

                                // Track transfer history
                                transferHistory.put(playerToTransfer, destinationTeam);

                                // Track money spent by the destination team
                                moneySpent.put(destinationTeam, moneySpent.getOrDefault(destinationTeam, 0.0) + negotiatedFee);

                                // Add the player to the destination team's roster
                                destinationTeam.addPlayer(playerToTransfer);

                                // Add the player to the playersBought map
                                playersBought.computeIfAbsent(destinationTeam, k -> new ArrayList<>()).add(playerToTransfer);

                                // Display the transfer in the log
                                transferMarketTextArea.append("Hour " + hour + ": ");
                                transferMarketTextArea.append(playerToTransfer.getName() + " has transferred to " + destinationTeam.getName()
                                        + " for $" + negotiatedFee + "m\n");
                                playerToTransfer.setFreeAgent(false);
                            } else {
                                // Transfer negotiation failed
                                transferMarketTextArea.append("Hour " + hour + ": ");
                                transferMarketTextArea.append(playerToTransfer.getName() + "'s transfer to " + destinationTeam.getName() + " fell through.\n");

                            }
                        } else {

                            if (playerToTransfer.getTransferPrice() <= destinationTeam.getTransferBudget()) {
                                // Simulate negotiation for transfer fee
                                int negotiatedFee = simulateNegotiation(playerToTransfer.getTransferPrice());

                                if (negotiatedFee > 0) {
                                    // Transfer fee paid from the destination team's budget
                                    destinationTeam.deductTransferBudget(negotiatedFee);

                                    // Track transfer history
                                    transferHistory.put(playerToTransfer, destinationTeam);

                                    //...
                                } else {
                                    // Transfer negotiation failed
                                    transferMarketTextArea.append("Hour " + hour + ": ");
                                    transferMarketTextArea.append(playerToTransfer.getName() + "'s transfer to " + destinationTeam.getName() + " fell through.\n");

                                }
                            } else {
                                // Player's transfer fee is too high for the destination team, so they opt for another player
                                transferMarketTextArea.append("Hour " + hour + ": ");
                                transferMarketTextArea.append(destinationTeam.getName() + " cannot afford " + playerToTransfer.getName() + ". Opting for another player.\n");

                                // Put the original player back into the available players pool
                                availablePlayers.add(playerToTransfer);

                                // Get another player from the available players pool
                                int anotherPlayerIndex = new Random().nextInt(availablePlayers.size());
                                Player anotherPlayer = availablePlayers.get(anotherPlayerIndex);
                                availablePlayers.remove(anotherPlayerIndex);

                                // Simulate negotiation for the new player
                                int negotiatedFee = simulateNegotiation(anotherPlayer.getTransferPrice());

                                if (negotiatedFee > 0 && anotherPlayer.getTransferPrice() <= destinationTeam.getTransferBudget()) {
                                    // Transfer fee paid from the destination team's budget
                                    destinationTeam.deductTransferBudget(negotiatedFee);

                                    // Track transfer history
                                    transferHistory.put(anotherPlayer, destinationTeam);

                                    //...
                                } else {
                                    // Transfer negotiation failed or the team still cannot afford the new player
                                    transferMarketTextArea.append("Hour " + hour + ": ");
                                    transferMarketTextArea.append(anotherPlayer.getName() + "'s transfer to " + destinationTeam.getName() + " fell through.\n");

                                }
                            }

                        }
                    }
                }
            } else {
                // Transfer window is closed
                transferMarketTextArea.append("Transfer window is closed.\n");

                // End the transfer window when the deadline is reached
                break;
            }

            // Update the transfer market display every hour
            try {
                Thread.sleep(1000); // Sleep for 1 second to simulate the passing of time
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // Display free agent transfers
        transferMarketTextArea.append("\nFree Agent Transfers:\n");
        for (Map.Entry<Player, Team> entry : freeAgentTransfers.entrySet()) {
            Player player = entry.getKey();
            Team destinationTeam = entry.getValue();
            transferMarketTextArea.append(player.getName() + " transferred as a free agent to " + destinationTeam.getName() + "\n");
        }

        // Display money spent by each team
        transferMarketTextArea.append("\nMoney Spent by Teams:\n");
        for (Map.Entry<Team, Double> entry : moneySpent.entrySet()) {
            Team team = entry.getKey();
            double spentAmount = entry.getValue();
            transferMarketTextArea.append(team.getName() + ": $" + spentAmount + "m\n");
        }

        // Display players bought by each team
        transferMarketTextArea.append("\nPlayers Bought by Teams:\n");
        for (Map.Entry<Team, List<Player>> entry : playersBought.entrySet()) {
            Team team = entry.getKey();
            List<Player> boughtPlayers = entry.getValue();
            transferMarketTextArea.append(team.getName() + ":\n");
            for (Player player : boughtPlayers) {
                transferMarketTextArea.append("  " + player.getName() + " (" + player.getPosition() + ") - $" + player.getTransferPrice() + "m\n");
            }
        }

        // At the end of the transfer window, assign remaining players to teams
        for (Player player : availablePlayers) {
            int randomTeamIndex = new Random().nextInt(teams.size());
            Team destinationTeam = teams.get(randomTeamIndex);
            destinationTeam.addPlayer(player);
        }

        // Update the team list and transfer market display
        updateTeamRosters();
        displayTransferMarket();
    }

    public void updateTeamRosters() {
        for (Team team : teams) {
            // Get the existing roster for the team
            List<Player> existingRoster = teamRosters.getOrDefault(team.getName(), new ArrayList<>());

            // Get the current players in the team object (including transferred players)
            List<Player> currentPlayers = team.getPlayers();

            // Add new players to the existing roster (checking for duplicates by name)
            for (Player player : currentPlayers) {
                boolean playerExists = false;
                for (Player existingPlayer : existingRoster) {
                    if (existingPlayer.getName().equals(player.getName())) {
                        playerExists = true;
                        break;
                    }
                }
                if (!playerExists) {
                    existingRoster.add(player);
                }
            }

            // Update the teamRosters map
            teamRosters.put(team.getName(), existingRoster);
        }
    }

    private int simulateNegotiation(int initialFee) {
        // Simulate a negotiation for the transfer fee
        int currentFee = initialFee;
        double negotiationFactor = 0.9; // 10% reduction in each round
        int rounds = 0;

        while (rounds < 3) {
            int proposedFee = (int) (currentFee * negotiationFactor);

            // Simulate acceptance probability (adjust as needed)
            double acceptanceProbability = 0.7; // 70% chance of acceptance
            if (Math.random() < acceptanceProbability) {
                // Deal accepted
                return proposedFee;
            }

            // Deal rejected, continue negotiation
            currentFee = proposedFee;
            negotiationFactor -= 0.1; // Reduce the reduction factor in each round
            rounds++;
        }

        // Negotiation failed
        return 0;
    }

    public void openViewTeam() {
        // Create a dialog to select a team to view
        String[] teamNames = new String[teams.size()];
        for (int i = 0; i < teams.size(); i++) {
            teamNames[i] = teams.get(i).getName();
        }

        String selectedTeam = (String) JOptionPane.showInputDialog(this, "Select a team to view:", "View Team",
                JOptionPane.QUESTION_MESSAGE, null, teamNames, teamNames[0]);

        if (selectedTeam != null) {
            // Find the selected team and display its information
            for (Team team : teams) {
                if (team.getName().equals(selectedTeam)) {
                    showTeamInfo(team);
                    break;
                }
            }
        }
    }

    public void showTeamInfo(Team team) {
        JFrame teamInfoFrame = new JFrame(team.getName() + " Formation");
        teamInfoFrame.setSize(600, 600);
        teamInfoFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        teamInfoFrame.setLocationRelativeTo(this);

        JPanel teamInfoPanel = new JPanel(new BorderLayout());
        teamInfoFrame.add(teamInfoPanel);

        JLabel formationLabel = new JLabel("Formation: " + team.getFormation());
        formationLabel.setFont(new Font("Arial", Font.BOLD, 20));
        formationLabel.setHorizontalAlignment(SwingConstants.CENTER);
        teamInfoPanel.add(formationLabel, BorderLayout.NORTH);

        JPanel playerInfoPanel = new JPanel(new GridLayout(0, 2, 10, 10)); // 2 columns for player name and rating
        teamInfoPanel.add(playerInfoPanel, BorderLayout.CENTER);

        List<Player> teamRoster = teamRosters.get(team.getName());

        if (teamRoster != null) {
            for (Player player : teamRoster) {
                JLabel playerNameLabel = new JLabel(player.getName());
                playerNameLabel.setFont(new Font("Arial", Font.PLAIN, 16));
                playerNameLabel.setHorizontalAlignment(SwingConstants.LEFT);

                JLabel playerRatingLabel = new JLabel("Rating: " + player.getRating());
                playerRatingLabel.setFont(new Font("Arial", Font.PLAIN, 16));
                playerRatingLabel.setHorizontalAlignment(SwingConstants.RIGHT);

                playerInfoPanel.add(playerNameLabel);
                playerInfoPanel.add(playerRatingLabel);
            }
        }

        teamInfoFrame.setVisible(true);
    }

    public void updateTeamList() {
        StringBuilder transferMarketStringBuilder = new StringBuilder();

        for (Team team : teams) {
            transferMarketStringBuilder.append(team.getName()).append(" - Budget: $")
                    .append(team.getTransferBudget()).append("m\n");

            List<Player> teamRoster = teamRosters.get(team.getName());
            if (teamRoster != null) {
                for (Player player : teamRoster) {
                    transferMarketStringBuilder.append("  ").append(player.getName()).append(" (")
                            .append(player.getPosition()).append(")\n");
                }
            }

            transferMarketStringBuilder.append("\n");
        }

        transferMarketTextArea.setText(transferMarketStringBuilder.toString());
    }

    public void displayTransferMarket() {
        updateTeamList();
        repaint();
    }

    public void simulateSeason() {
        int totalMatchesPerTeam = 38; // Number of matches per team in a season

        for (int matchDay = 1; matchDay <= totalMatchesPerTeam; matchDay++) {
            simulateMatchDay(matchDay);

        }

        displaySeasonSummary();
    }

    private void simulateMatchDay(int matchDay) {
        for (Team team : teams) {
            simulateTeamPerformance(team, matchDay);
        }

        // Update team standings after each match day
        updateTeamStandings();
    }

    private void simulateTeamPerformance(Team team, int matchDay) {

        // Calculate team rating as average of player ratings
        int sumPlayerRatings = 0;
        for (Player player : team.getPlayers()) {
            sumPlayerRatings += player.getRating();
        }
        int teamRating = 0; // Default rating if no players
        if (team.getPlayers().size() > 0) {
            teamRating = sumPlayerRatings / team.getPlayers().size();
        }

        // Adjust scoring based on team rating and randomness
        int goalsScored, goalsConceded;
        Random random = new Random();

        if (teamRating < 3) {
            goalsScored = random.nextInt(5); // Lower scoring teams
            goalsConceded = random.nextInt(2) + 1; // More likely to concede
        } else if (teamRating >= 3 && teamRating < 6) {
            goalsScored = random.nextInt(7); // Mid-range scoring teams
            goalsConceded = random.nextInt(3); // Average defense
        } else { // Team rating >= 6
            goalsScored = random.nextInt(9); // Higher scoring teams
            goalsConceded = random.nextInt(2); // Strong defense
        }

        // Add some randomness to the results
        int randomFactor = random.nextInt(3) - 1; // -1, 0, or 1
        goalsScored += randomFactor;
        goalsConceded += randomFactor;

        // Ensure goals scored and conceded are non-negative
        goalsScored = Math.max(0, goalsScored);
        goalsConceded = Math.max(0, goalsConceded);

        // Update team statistics 
        team.updateStatistics(goalsScored, goalsConceded);
    }

    private void updateTeamStandings() {
        // Calculate team standings based on points and goal difference
        List<Team> sortedTeams = new ArrayList<>(teams);
        sortedTeams.sort(Comparator.comparingInt(this::calculateTeamPoints)
                .thenComparingInt(Team::getGoalDifference).reversed());

        // Update team standings map
        teamStandings.clear();
        for (int i = 0; i < sortedTeams.size(); i++) {
            teamStandings.put(sortedTeams.get(i).getName(), i + 1);
        }
    }

    private int calculateTeamPoints(Team team) {
        // Calculate team points based on wins, draws, and losses
        int wins = team.getWins();
        int draws = team.getDraws();
        return (wins * 3) + draws;
    }

    private void displaySeasonSummary() {
        // Display season summary including final standings and player performances
        List<Team> sortedTeams = new ArrayList<>(teams);
        sortedTeams.sort(Comparator.comparingInt((Team team) -> calculateTeamPoints(team))
                .thenComparingInt(Team::getGoalDifference).reversed()
                .thenComparing(Team::getName));
        StringBuilder summaryBuilder = new StringBuilder();
        summaryBuilder.append("\n\n");
        summaryBuilder.append("\n\nFinal Standings:\n\n");

        summaryBuilder.append(String.format("%-20s %-10s %-15s %n", "Team", "Points", "GD"));
        summaryBuilder.append(String.format("%-20s %-10s %-15s %n", "--------------------", "----------", "-------------"));

        for (Team team : sortedTeams) {
            summaryBuilder.append(String.format("%-20s %-10s %-15s %n", team.getName(),
                    calculateTeamPoints(team), team.getGoalDifference()));
        }
        System.out.println(summaryBuilder.toString());

        // Display team statistics and player performances
        for (Team team : teams) {
            summaryBuilder.append("\n").append("Team: ").append(team.getName()).append("\n");
            summaryBuilder.append("Points: ").append(calculateTeamPoints(team)).append("\n");
            summaryBuilder.append("Goals Scored: ").append(team.getGoalsScored()).append("\n");
            summaryBuilder.append("Goals Conceded: ").append(team.getGoalsConceded()).append("\n");

            // Display player performances
            summaryBuilder.append("\nPlayer Performances:\n");
            List<Player> teamRoster = team.getPlayers();
            for (Player player : teamRoster) {
                summaryBuilder.append(player.getName()).append(" - Rating: ").append(player.simulatePlayerPerformance()).append("\n");
            }
        }

        JTextArea seasonSummaryTextArea = new JTextArea(summaryBuilder.toString());
        seasonSummaryTextArea.setFont(new Font("Consolas", Font.PLAIN, 16));

        JScrollPane seasonSummaryScrollPane = new JScrollPane(seasonSummaryTextArea);
        seasonSummaryScrollPane.setBounds(800, 50, 400, 600);
        add(seasonSummaryScrollPane);

        repaint();
    }

    private Team getTeamByName(String name) {
        for (Team team : teams) {
            if (team.getName().equals(name)) {
                return team;
            }
        }
        return null;
    }
}

class Team {

    private String name;
    private double transferBudget;
    private String formation;
    private List<Player> players;
    private int wins;
    private int draws;
    private int goalsScored;
    private int goalsConceded;

    public Team(String name, double transferBudget, String formation) {
        this.name = name;
        this.transferBudget = transferBudget;
        this.formation = formation;
        this.players = new ArrayList<>();
    }

    public String getName() {
        return name;
    }

    public double getTransferBudget() {
        return transferBudget;
    }

    public String getFormation() {
        return formation;
    }

    public List<Player> getPlayers() {
        return players;
    }

    public void addPlayer(Player player) {
        if (players.contains(player)) {
            players.add(player);
        }
    }

    public void deductTransferBudget(double amount) {
        transferBudget -= amount;
    }

    public int getWins() {
        return wins;
    }

    public int getDraws() {
        return draws;
    }

    public int getGoalsScored() {
        return goalsScored;
    }

    public int getGoalsConceded() {
        return goalsConceded;
    }

    public int getGoalDifference() {
        return goalsScored - goalsConceded;
    }

    public void updateStatistics(int goalsScored, int goalsConceded) {
        // Update team statistics based on match results
        if (goalsScored > goalsConceded) {
            wins++;
        } else if (goalsScored == goalsConceded) {
            draws++;
        }

        this.goalsScored += goalsScored;
        this.goalsConceded += goalsConceded;
    }
}

class Player {

    private String name;
    private String position;
    private int transferPrice;
    private int rating;
    private String previousClub;
    private String transferStatus;
    private boolean isFreeAgent;
    private boolean isPicked;

    public Player(String name, String position, int transferPrice, int rating, String previousClub) {
        this.name = name;
        this.position = position;
        this.transferPrice = transferPrice;
        this.rating = rating;
        this.previousClub = previousClub;
        this.transferStatus = "Unassigned";
    }

    public String getName() {
        return name;
    }

    public String getPosition() {
        return position;
    }

    public int getTransferPrice() {
        return transferPrice;
    }

    public int getRating() {
        return rating;
    }

    public String getPreviousClub() {
        return previousClub;
    }

    public void setPreviousClub(String previousClub) {
        this.previousClub = previousClub;
    }

    public String getTransferStatus() {
        return transferStatus;
    }

    public void setTransferStatus(String transferStatus) {
        this.transferStatus = transferStatus;
    }

    public boolean isFreeAgent() {
        return isFreeAgent;
    }

    public void setFreeAgent(boolean freeAgent) {
        isFreeAgent = freeAgent;
    }

    public boolean isPicked() {
        return isPicked;
    }

    public void setPicked(boolean picked) {
        isPicked = picked;
    }

    public int simulatePlayerPerformance() {
        // Simulate player performance based on various factors
        int talent = new Random().nextInt(2); // Random talent between 0 and 2
        int sharpness = new Random().nextInt(3); // Random sharpness between 0 and 2
        int defensiveContributions = new Random().nextInt(3); // Random defensive contributions between 0 and 2
        int threat = new Random().nextInt(3); // Random threat between 0 and 2
        int offensiveContributions = new Random().nextInt(3); // Random offensive contributions between 0 and 2
        int creativity = new Random().nextInt(3); // Random creativity between 0 and 2

        // Calculate overall rating based on various factors
        int overallRating = (talent * 2) + (sharpness * 1) + (defensiveContributions * 1)
                + (threat * 1) + (offensiveContributions * 1) + (creativity * 1);

        return overallRating;
    }

} are there any errors or logic mistakes in terms of the game