theres duplicate players when i checked. i did generate roster then transfer market then view teams. 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<List<Match>> fixtures; 
    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) {
    int currentFee = initialFee;
    double minFee = initialFee * 0.75; // Selling club won't accept less than 75% of initial fee
    int maxRounds = 5;
    Random random = new Random();

    for (int round = 1; round <= maxRounds; round++) {
        // Buyer's new offer
        int offer = (int) (currentFee * (0.95 - random.nextDouble() * 0.1)); // Reduce 5-15%

        // Simulate selling club's acceptance based on offer
        double acceptanceProbability = (double) offer / initialFee; // Higher offer, higher chance
        double randomValue = random.nextDouble();

        if (offer >= minFee && randomValue <= acceptanceProbability) {
            // Selling club accepts the offer
            return offer;
        } else {
            // Selling club rejects, adjust current fee for next round
            currentFee = offer;
        }
    }
    // 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();
    }

class Match {
    private Team homeTeam;
    private Team awayTeam;
    private int homeGoals;
    private int awayGoals;

    public Match(Team homeTeam, Team awayTeam) {
        this.homeTeam = homeTeam;
        this.awayTeam = awayTeam;
        homeGoals = 0;
        awayGoals = 0;
    }

    public Team getHomeTeam() {
        return homeTeam;
    }

    public Team getAwayTeam() {
        return awayTeam;
    }

    public int getHomeGoals() {
        return homeGoals;
    }

    public int getAwayGoals() {
        return awayGoals;
    }

    public void setResult(int homeGoals, int awayGoals) {
        this.homeGoals = homeGoals;
        this.awayGoals = awayGoals;
    }
}    
    
    public void simulateSeason() {
        // Generate fixtures
        fixtures = generateFixtures(teams);

        int matchDayNumber = 1;

        for (List<Match> matchDay : fixtures) {
            simulateMatchDay(matchDay, matchDayNumber);
            matchDayNumber++;
            // Update team standings after each match day if needed
            updateTeamStandings();
        }

        displaySeasonSummary();
    }

    private List<List<Match>> generateFixtures(List<Team> teams) {
        int numTeams = teams.size();

        List<List<Match>> fixtures = new ArrayList<>();

        List<Team> teamsCopy = new ArrayList<>(teams); // Make a copy to avoid modifying the original list

        if (numTeams % 2 != 0) {
            // If the number of teams is odd, add a dummy team which will get a bye
            teamsCopy.add(null);
            numTeams++;
        }

        int totalRounds = numTeams - 1;
        int matchesPerRound = numTeams / 2;

        for (int round = 0; round < totalRounds; round++) {
            List<Match> roundMatches = new ArrayList<>();

            for (int match = 0; match < matchesPerRound; match++) {
                int home = (round + match) % (numTeams - 1);
                int away = (numTeams - 1 - match + round) % (numTeams - 1);

                if (match == 0) {
                    away = numTeams - 1;
                }

                Team homeTeam = teamsCopy.get(home);
                Team awayTeam = teamsCopy.get(away);

                if (homeTeam != null && awayTeam != null) {
                    Match fixture = new Match(homeTeam, awayTeam);
                    roundMatches.add(fixture);
                }
            }

            fixtures.add(roundMatches);
        }

        // Now create return matches (second half of the season)
        List<List<Match>> returnFixtures = new ArrayList<>();

        for (List<Match> roundMatches : fixtures) {
            List<Match> returnRound = new ArrayList<>();
            for (Match match : roundMatches) {
                // Swap home and away teams
                Match returnMatch = new Match(match.getAwayTeam(), match.getHomeTeam());
                returnRound.add(returnMatch);
            }
            returnFixtures.add(returnRound);
        }

        // Combine the fixtures into the full season
        fixtures.addAll(returnFixtures);

        return fixtures;
    }

    private void simulateMatchDay(List<Match> matchDay, int matchDayNumber) {
        for (Match match : matchDay) {
            simulateMatch(match);
        }

        // Optionally, print match day results
        displayMatchDayResults(matchDay, matchDayNumber);
    }    
    
    private void simulateMatch(Match match) {
        Team homeTeam = match.getHomeTeam();
        Team awayTeam = match.getAwayTeam();

        double homeTeamRating = getTeamRating(homeTeam);
        double awayTeamRating = getTeamRating(awayTeam);

        // Apply home advantage
        homeTeamRating *= 1.1; // Increase home team rating by 10%

        // Expected goals calculation
        double homeExpectedGoals = (homeTeamRating / (homeTeamRating + awayTeamRating)) * 2.0;
        double awayExpectedGoals = (awayTeamRating / (homeTeamRating + awayTeamRating)) * 1.5;

        // Simulate goals using a Poisson distribution approximation
        int homeGoals = simulateGoals(homeExpectedGoals);
        int awayGoals = simulateGoals(awayExpectedGoals);

        // Set the match result
        match.setResult(homeGoals, awayGoals);

        // Update team statistics
        homeTeam.updateStatistics(homeGoals, awayGoals);
        awayTeam.updateStatistics(awayGoals, homeGoals); // Swap for the away team

        // Update wins, draws, losses
        if (homeGoals > awayGoals) {
            homeTeam.incrementWins();
            awayTeam.incrementLosses();
        } else if (homeGoals < awayGoals) {
            awayTeam.incrementWins();
            homeTeam.incrementLosses();
        } else {
            homeTeam.incrementDraws();
            awayTeam.incrementDraws();
        }
    }

    private double getTeamRating(Team team) {
        int sumRatings = 0;
        for (Player player : team.getPlayers()) {
            sumRatings += player.getRating();
        }
        if (team.getPlayers().size() > 0) {
            return (double) sumRatings / team.getPlayers().size();
        } else {
            return 1.0;   // Assign minimal rating if no players
        }
    }

    private int simulateGoals(double lambda) {
        // Simulate goals using a Poisson distribution approximation
        double L = Math.exp(-lambda);
        double p = 1.0;
        int k = 0;

        do {
            k++;
            p *= Math.random();
        } while (p > L);

        return k - 1;
    }    
    
    private void displayMatchDayResults(List<Match> matchDay, int matchDayNumber) {
        StringBuilder resultsBuilder = new StringBuilder();
        resultsBuilder.append("Match Day ").append(matchDayNumber).append(" Results:\n");

        for (Match match : matchDay) {
            resultsBuilder.append(match.getHomeTeam().getName())
                    .append(" ")
                    .append(match.getHomeGoals())
                    .append(" - ")
                    .append(match.getAwayGoals())
                    .append(" ")
                    .append(match.getAwayTeam().getName())
                    .append("\n");
        }

        // Optionally, display the results in the GUI, or print to console
        // For now, let's print to console
        System.out.println(resultsBuilder.toString());
    }    

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

        StringBuilder summaryBuilder = new StringBuilder();
        summaryBuilder.append("\n\nFinal Standings:\n\n");

        summaryBuilder.append(String.format("%-20s %-10s %-5s %-5s %-5s %-5s %-5s %-10s%n",
                "Team", "Points", "W", "D", "L", "GF", "GA", "GD"));
        summaryBuilder.append(String.format("%-20s %-10s %-5s %-5s %-5s %-5s %-5s %-10s%n",
                "--------------------", "------", "-", "-", "-", "--", "--", "----"));

        for (Team team : sortedTeams) {
            summaryBuilder.append(String.format("%-20s %-10d %-5d %-5d %-5d %-5d %-5d %-10d%n",
                    team.getName(), calculateTeamPoints(team), team.getWins(), team.getDraws(),
                    team.getLosses(), team.getGoalsScored(), team.getGoalsConceded(), 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 losses;
    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<>();
        this.wins = 0;
        this.draws = 0;
        this.losses = 0;
        this.goalsScored = 0;
        this.goalsConceded = 0;
    }

    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 getGoalsScored() {
        return goalsScored;
    }

    public int getGoalsConceded() {
        return goalsConceded;
    }

    public int getGoalDifference() {
        return goalsScored - goalsConceded;
    }
    
    public void incrementWins() {
        wins++;
    }

    public void incrementDraws() {
        draws++;
    }

    public void incrementLosses() {
        losses++;
    }

    public void updateStatistics(int goalsScored, int goalsConceded) {
        this.goalsScored += goalsScored;
        this.goalsConceded += goalsConceded;
    }

    public int getWins() {
        return wins;
    }

    public int getDraws() {
        return draws;
    }

    public int getLosses() {
        return losses;
    }
}

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() {
    Random random = new Random();
    int performanceVariation = random.nextInt(5) - 2; // Variation between -2 and +2
    int performance = this.rating + performanceVariation;
    performance = Math.max(1, performance); // Ensure minimum performance
    return performance;
}

}