package pp.monopoly.game.client;

import com.jme3.scene.Spatial;
import com.simsilica.lemur.Button;
import com.simsilica.lemur.TextField;
import org.junit.Before;
import org.junit.Test;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.game.server.Player;
import pp.monopoly.message.server.DiceResult;
import pp.monopoly.notification.ClientStateEvent;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

public class ClientGameLogicTest {

    private MonopolyApp app;

    private MonopolyApp app;
    private NewGameMenu newGameMenu;

    @Before
    public void setUp() {
        app = new MonopolyApp();
        app.simpleInitApp(); // Initialisiert die App mit GUI und Spielzuständen
        newGameMenu = new NewGameMenu();
    }

    @Test
    // T006: UC-game-06 - Testet, ob das Spielmenü geöffnet wird, wenn der Spieler im Spiel „ESC“ drückt
    public void testOpenGameMenuWithESC() {
        app.escape(true); // Simuliert das Drücken der ESC-Taste

        Spatial gameMenu = app.getGuiNode().getChild("GameMenu");
        assertNotNull("Das Spielmenü sollte sichtbar sein, nachdem ESC gedrückt wurde", gameMenu);
    }

    @Test
    // T007: UC-game-07 - Testet, ob der Spieler erfolgreich den Namen des Hosts eingeben kann
    public void testEnterHostName() {
        Spatial hostNameField = app.getGuiNode().getChild("HostNameField");
        assertNotNull("Das Eingabefeld für den Hostnamen sollte sichtbar sein", hostNameField);

        if (hostNameField instanceof TextField) {
            TextField hostNameInput = (TextField) hostNameField;
            hostNameInput.setText("TestHost");

            assertEquals("Der eingegebene Hostname sollte 'TestHost' sein", "TestHost", hostNameInput.getText());
        }
        else {
            throw new AssertionError("'HostNameField' ist kein TextField-Objekt.");
        }
    }

    @Test
    // T008: UC-game-08 - Testet, ob der Spieler die Portnummer des Hosts eingeben kann
    public void testEnterPortNumber() {
        Spatial portNumberField = app.getGuiNode().getChild("PortNumberField");
        assertNotNull("Das Eingabefeld für die Portnummer sollte sichtbar sein", portNumberField);

        if (portNumberField instanceof TextField) {
            TextField portNumberInput = (TextField) portNumberField;
            portNumberInput.setText("12345");

            assertEquals("Die eingegebene Portnummer sollte '12345' sein", "12345", portNumberInput.getText());
        }
        else {
            throw new AssertionError("'PortNumberField' ist kein TextField-Objekt.");
        }
    }

    @Test
    // T009: UC-game-09 - Testet, ob der Spieler das Erstellen eines Spiels abbrechen kann
    public void testCancelGameCreation() {
        Spatial cancelButtonSpatial = app.getGuiNode().getChild("CancelButton");
        assertNotNull("Der 'Abbrechen'-Button sollte existieren", cancelButtonSpatial);

        if (cancelButtonSpatial instanceof Button) {
            Button cancelButton = (Button) cancelButtonSpatial;
            cancelButton.click();

            Spatial mainMenu = app.getGuiNode().getChild("MainMenu");
            assertNotNull("Das Hauptmenü sollte nach dem Abbrechen des Spiels sichtbar sein", mainMenu);
        }
        else {
            throw new AssertionError("'CancelButton' ist kein Button-Objekt.");
        }
    }

    /*
        @Test
        // T010: UC-game-10 - Testet, ob der Spieler die Spielerlobby betreten kann
        public void testEnterPlayerLobby() {
            app.receivedEvent(new pp.monopoly.notification.ClientStateEvent(pp.monopoly.notification.ClientStateEvent.State.LOBBY));

            Spatial playerLobby = app.getGuiNode().getChild("PlayerLobby");
            assertNotNull("Die Spielerlobby sollte nach dem Beitritt sichtbar sein", playerLobby);
        }


        @Test
        // T010: UC-game-10 - Testet, ob der Spieler die Spielerlobby betreten kann
        public void testEnterPlayerLobby() {
            // Simuliert den Empfang eines ClientStateEvent für den Lobby-State
            app.receivedEvent(new ClientStateEvent(ClientStateEvent.State.LOBBY));

            // Überprüft, ob das Lobby-UI sichtbar ist
            Spatial playerLobby = app.getGuiNode().getChild("PlayerLobby");
            assertNotNull("Die Spielerlobby sollte nach dem Beitritt sichtbar sein", playerLobby);
    */
    @Test
    // T011: UC-game-11 - Testet, ob der hostende Spieler einen Startbetrag eingeben kann
    public void testEnterStartingCapital() {
        Spatial startingCapitalField = app.getGuiNode().getChild("StartingCapitalField");
        assertNotNull("Das Eingabefeld für den Startbetrag sollte existieren", startingCapitalField);

        if (startingCapitalField instanceof TextField) {
            TextField startingCapitalInput = (TextField) startingCapitalField;
            startingCapitalInput.setText("1500");

            assertEquals("Der eingegebene Startbetrag sollte '1500' sein", "1500", startingCapitalInput.getText());
        }
        else {
            throw new AssertionError("'StartingCapitalField' ist kein TextField-Objekt.");
        }
    }

    @Test
    // T012: UC-game-12 - Testet, ob der Spieler den Startbetrag um 100 € erhöhen kann
    public void testIncreaseStartingCapital() {
        Spatial increaseButton = app.getGuiNode().getChild("IncreaseCapitalButton");
        assertNotNull("Der 'Erhöhen'-Button sollte existieren", increaseButton);

        if (increaseButton instanceof Button) {
            Button increaseCapitalButton = (Button) increaseButton;
            increaseCapitalButton.click();

            Spatial startingCapitalField = app.getGuiNode().getChild("StartingCapitalField");
            if (startingCapitalField instanceof TextField) {
                TextField startingCapitalInput = (TextField) startingCapitalField;
                assertEquals("Der Startbetrag sollte um 100 erhöht worden sein", "1600", startingCapitalInput.getText());
            }
            else {
                throw new AssertionError("'StartingCapitalField' ist kein TextField-Objekt.");
            }
        }
        else {
            throw new AssertionError("'IncreaseCapitalButton' ist kein Button-Objekt.");
        }
    }

    @Test
    // T013: UC-game-13 - Testet, ob der Spieler den Startbetrag um 100 € senken kann
    public void testDecreaseStartingCapital() {
        Spatial decreaseButton = app.getGuiNode().getChild("DecreaseCapitalButton");
        assertNotNull("Der 'Senken'-Button sollte existieren", decreaseButton);

        if (decreaseButton instanceof Button) {
            Button decreaseCapitalButton = (Button) decreaseButton;
            decreaseCapitalButton.click();

            Spatial startingCapitalField = app.getGuiNode().getChild("StartingCapitalField");
            if (startingCapitalField instanceof TextField) {
                TextField startingCapitalInput = (TextField) startingCapitalField;
                assertEquals("Der Startbetrag sollte um 100 gesenkt worden sein", "1400", startingCapitalInput.getText());
            }
            else {
                throw new AssertionError("'StartingCapitalField' ist kein TextField-Objekt.");
            }
        }
        else {
            throw new AssertionError("'DecreaseCapitalButton' ist kein Button-Objekt.");
        }
    }

    @Test
    // T014: UC-game-14 - Testet, ob die Standard-Spielernamen korrekt voreingestellt sind
    public void testDefaultPlayerName() {
        Spatial playerNameField = app.getGuiNode().getChild("PlayerNameField");
        assertNotNull("Das Eingabefeld für den Spielernamen sollte existieren", playerNameField);

        if (playerNameField instanceof TextField) {
            TextField playerNameInput = (TextField) playerNameField;
            assertEquals("Der voreingestellte Spielername sollte 'Spieler 1' sein", "Spieler 1", playerNameInput.getText());
        }
        else {
            throw new AssertionError("'PlayerNameField' ist kein TextField-Objekt.");
        }
    }

    @Test
    // T015: UC-game-15 - Testet, ob der Spieler einen Anzeigenamen eingeben kann
    public void testEnterDisplayName() {
        Spatial displayNameField = app.getGuiNode().getChild("DisplayNameField");
        assertNotNull("Das Eingabefeld für den Anzeigenamen sollte existieren", displayNameField);

        if (displayNameField instanceof TextField) {
            TextField displayNameInput = (TextField) displayNameField;
            displayNameInput.setText("MaxMustermann");

            assertEquals("Der eingegebene Anzeigename sollte 'MaxMustermann' sein", "MaxMustermann", displayNameInput.getText());
        }
        else {
            throw new AssertionError("'DisplayNameField' ist kein TextField-Objekt.");
        }
    }

    @Test
    // T016: UC-game-16 - Testet, ob eine Warnung angezeigt wird, wenn ein Spieler einen bereits belegten Namen eingibt
    public void testDuplicateNameEntry() {
        Spatial playerNameField = app.getGuiNode().getChild("PlayerNameField");
        assertNotNull("Das Eingabefeld für den Spielernamen sollte existieren", playerNameField);

        if (playerNameField instanceof TextField) {
            TextField playerNameInput = (TextField) playerNameField;
            playerNameInput.setText("Spieler 1");
            app.getGuiNode().getChild("AddPlayerButton").click(); // Spieler hinzufügen
            playerNameInput.setText("Spieler 1");
            app.getGuiNode().getChild("AddPlayerButton").click(); // Spieler mit gleichem Namen hinzufügen

            Spatial warning = app.getGuiNode().getChild("DuplicateNameWarning");
            assertNotNull("Es sollte eine Warnung angezeigt werden, wenn ein Name doppelt vergeben wird", warning);
        }
        else {
            throw new AssertionError("'PlayerNameField' ist kein TextField-Objekt.");
        }
    }

    @Test
    // T017: UC-game-17 - Testet, ob der Spieler eine verfügbare Spielfigurfarbe auswählen kann
    public void testSelectPlayerColor() {
        Spatial colorSelector = app.getGuiNode().getChild("ColorSelector");
        assertNotNull("Der Farbwähler sollte existieren", colorSelector);

        if (colorSelector instanceof Button) {
            Button colorButton = (Button) colorSelector;
            colorButton.click();

            Spatial selectedColor = app.getGuiNode().getChild("SelectedColor");
            assertNotNull("Die gewählte Farbe sollte sichtbar sein", selectedColor);
        }
        else {
            throw new AssertionError("'ColorSelector' ist kein Button-Objekt.");
        }
    }

    @Test
    // T018: UC-game-18 - Testet, ob eine belegte Spielfigurfarbe nicht ausgewählt werden kann
    public void testSelectOccupiedColor() {
        app.getGuiNode().getChild("ColorSelectorRed").click(); // Spieler 1 wählt Rot
        app.getGuiNode().getChild("AddPlayerButton").click(); // Spieler 1 hinzufügen

        app.getGuiNode().getChild("ColorSelectorRed").click(); // Spieler 2 versucht Rot zu wählen
        Spatial warning = app.getGuiNode().getChild("ColorOccupiedWarning");
        assertNotNull("Es sollte eine Warnung angezeigt werden, wenn eine belegte Farbe ausgewählt wird", warning);
    }

    @Test
    // T019: UC-game-19 - Testet, ob der Spieler eine Spielfigur auswählen kann
    public void testSelectPlayerToken() {
        Spatial tokenSelector = app.getGuiNode().getChild("TokenSelector");
        assertNotNull("Der Token-Wähler sollte existieren", tokenSelector);

        if (tokenSelector instanceof Button) {
            Button tokenButton = (Button) tokenSelector;
            tokenButton.click();

            Spatial selectedToken = app.getGuiNode().getChild("SelectedToken");
            assertNotNull("Die gewählte Spielfigur sollte sichtbar sein", selectedToken);
        }
        else {
            throw new AssertionError("'TokenSelector' ist kein Button-Objekt.");
        }
    }

    @Test
    // T020: UC-game-20 - Testet, ob eine belegte Spielfigur nicht ausgewählt werden kann
    public void testSelectOccupiedToken() {
        app.getGuiNode().getChild("TokenSelectorShip").click();
        app.getGuiNode().getChild("AddPlayerButton").click();

        app.getGuiNode().getChild("TokenSelectorShip").click();
        Spatial warning = app.getGuiNode().getChild("TokenOccupiedWarning");
        assertNotNull("Es sollte eine Warnung angezeigt werden, wenn eine belegte Spielfigur ausgewählt wird", warning);
    }

    @Test
    // T021: UC-game-14 - Überprüft, ob der Spieler zur „Spiel erstellen“-Ansicht zurückkehrt, wenn Abbrechen gedrückt wird
    public void testCancelPlayerLobby() {
        Spatial cancelButtonSpatial = app.getGuiNode().getChild("CancelLobbyButton");
        assertNotNull("Der 'Abbrechen'-Button in der Lobby sollte existieren", cancelButtonSpatial);

        if (cancelButtonSpatial instanceof Button) {
            Button cancelButton = (Button) cancelButtonSpatial;
            cancelButton.click();

            Spatial mainMenu = app.getGuiNode().getChild("MainMenu");
            assertNotNull("Das Hauptmenü sollte nach dem Abbrechen der Lobby sichtbar sein", mainMenu);
        }
        else {
            throw new AssertionError("'CancelLobbyButton' ist kein Button-Objekt.");
        }
    }

    @Test
    // T022: UC-game-15 - Überprüft, ob das Spielmenü in der Lobby durch Drücken der ESC-Taste geöffnet wird
    public void testOpenLobbyMenuWithESC() {
        app.escape(true); // Simuliert das Drücken der ESC-Taste

        Spatial lobbyMenu = app.getGuiNode().getChild("LobbyMenu");
        assertNotNull("Das Lobby-Menü sollte sichtbar sein, nachdem ESC in der Lobby gedrückt wurde", lobbyMenu);
    }

    @Test
    // T023: UC-game-16 - Testet, ob der Spieler die Auswahl der Spielfigur bestätigen kann
    public void testPlayerReadyConfirmation() {
        Spatial confirmButtonSpatial = app.getGuiNode().getChild("ConfirmTokenButton");
        assertNotNull("Der 'Bestätigen'-Button für die Spielfigur sollte existieren", confirmButtonSpatial);

        if (confirmButtonSpatial instanceof Button) {
            Button confirmButton = (Button) confirmButtonSpatial;
            confirmButton.click();

            Spatial readyStatus = app.getGuiNode().getChild("PlayerReadyStatus");
            assertNotNull("Der Status 'Bereit' sollte angezeigt werden, nachdem die Spielfigur bestätigt wurde", readyStatus);
        }
        else {
            throw new AssertionError("'ConfirmTokenButton' ist kein Button-Objekt.");
        }
    }
        @Test
        // T024: UC-game-16 - Überprüft, ob das Spiel startet, wenn alle Spieler ihre Auswahl bestätigt haben
        public void testAllPlayersReady() {
            app.receivedEvent(new pp.monopoly.notification.ClientStateEvent(pp.monopoly.notification.ClientStateEvent.State.ALL_PLAYERS_READY));

            Spatial gameScreen = app.getGuiNode().getChild("GameScreen");
            assertNotNull("Das Spiel sollte starten, wenn alle Spieler bereit sind", gameScreen);
        }
        @Test
        // T025: UC-game-17 - Testet, ob das Einstellungen-Menü während des Spiels geöffnet wird
        public void testOpenMainGameSettings () {
            app.escape(true);

            Spatial settingsButton = app.getGuiNode().getChild("SettingsButton");
            assertNotNull("Der 'Einstellungen'-Button sollte im Spielmenü vorhanden sein", settingsButton);

            if (settingsButton instanceof Button) {
                ((Button) settingsButton).click();
                Spatial settingsMenu = app.getGuiNode().getChild("SettingsMenu");
                assertNotNull("Das Einstellungen-Menü sollte im Spiel angezeigt werden", settingsMenu);
            }
            else {
                throw new AssertionError("'SettingsButton' ist kein Button-Objekt.");
            }
        }

    @Test
// T026: UC-gameplay-01 - Überprüft, ob der Spieler erfolgreich würfeln kann
    public void testRollDice() {
        Spatial rollDiceButton = app.getGuiNode().getChild("RollDiceButton");
        assertNotNull("Der 'Würfeln'-Button sollte sichtbar sein", rollDiceButton);

        if (rollDiceButton instanceof Button) {
            ((Button) rollDiceButton).click(); // Simuliert einen Würfelwurf
            Spatial diceResult = app.getGuiNode().getChild("DiceResult");
            assertNotNull("Das Ergebnis des Würfelwurfs sollte angezeigt werden", diceResult);
        }
    }
    @Test
// T027: UC-gameplay-01 - Überprüft, ob der aktive Spieler die richtige Anzahl an Feldern basierend auf dem Wurf bewegt
    public void testMovePlayerAutomatically() {
        Game game = new Game(); // Initialisiert ein neues Spiel
        PlayerHandler playerHandler = game.getPlayerHandler(); // Holt den PlayerHandler, der die Spieler verwaltet

        Player activePlayer = playerHandler.getActivePlayer(); // Holt den aktuellen aktiven Spieler
        assertNotNull("Es sollte einen aktiven Spieler geben", activePlayer);

        DiceResult diceResult = game.rollDice(); // Würfelwurf simulieren
        int steps = diceResult.getTotal();

        int initialPosition = activePlayer.getFieldId(); // Ursprüngliche Position des aktiven Spielers
        playerHandler.moveActivePlayer(steps); // Bewegt den aktiven Spieler basierend auf dem Wurf

        int expectedPosition = (initialPosition + steps) % game.getGameBoard().getNumberOfFields(); // Zielposition berechnen
        int newPosition = activePlayer.getFieldId();

        assertEquals("Der aktive Spieler sollte sich korrekt bewegen", expectedPosition, newPosition);

        // Überprüfen, dass alle anderen Spieler im WaitForTurn-State bleiben
        playerHandler.getPlayers().stream()
                     .filter(player -> player != activePlayer)
                     .forEach(player -> assertTrue("Andere Spieler sollten im WaitForTurn-State sein", player.getState() instanceof WaitForTurnState));
    }

    @Test
// T028: UC-gameplay-02 - Überprüft, ob die Würfel zufällige Zahlen generieren
    public void testGenerationDice() {
        boolean isRandom = false;
        DiceResult previousResult = null;

        for (int i = 0; i < 10; i++) {
            DiceResult currentResult = app.getGame().rollDice();

            assertNotNull("Das Würfelergebnis sollte nicht null sein", currentResult);
            assertTrue("Die Würfelzahl 1 sollte zwischen 1 und 6 liegen", currentResult.getDice1() >= 1 && currentResult.getDice1() <= 6);
            assertTrue("Die Würfelzahl 2 sollte zwischen 1 und 6 liegen", currentResult.getDice2() >= 1 && currentResult.getDice2() <= 6);

            if (previousResult != null && (currentResult.getDice1() != previousResult.getDice1() || currentResult.getDice2() != previousResult.getDice2())) {
                isRandom = true; // Unterschiedliche Würfelwerte gefunden
                break;
            }
            previousResult = currentResult;
        }
        assertTrue("Die Würfelergebnisse sollten zufällig sein", isRandom);
    }

    @Test
// T029: UC-gameplay-03 - Überprüft, ob die richtigen Augenzahlen angezeigt werden
    public void testDisplayResults() {
        DiceResult result = app.getGame().rollDice();

        assertNotNull("Das Würfelergebnis sollte nicht null sein", result);
        assertTrue("Die Würfelzahl 1 sollte zwischen 1 und 6 liegen", result.getDice1() >= 1 && result.getDice1() <= 6);
        assertTrue("Die Würfelzahl 2 sollte zwischen 1 und 6 liegen", result.getDice2() >= 1 && result.getDice2() <= 6);
        assertEquals("Die Summe sollte korrekt berechnet werden", result.getDice1() + result.getDice2(), result.getTotal());
    }
    @Test
    // T030: UC-gameplay-04 - Überprüfen, ob die Summe der Würfelergebnisse korrekt berechnet wird
    public void testSumDiceResults() {
        Spatial rollDiceButton = app.getGuiNode().getChild("RollDiceButton");
        assertNotNull("Der 'Würfeln'-Button sollte sichtbar sein", rollDiceButton);

        if (rollDiceButton instanceof Button) {
            ((Button) rollDiceButton).click(); // Simuliert einen Würfelwurf
            Spatial diceResult1 = app.getGuiNode().getChild("DiceResult1");
            Spatial diceResult2 = app.getGuiNode().getChild("DiceResult2");

            assertNotNull("Die Ergebnisse des Würfelwurfs sollten angezeigt werden", diceResult1);
            assertNotNull("Die Ergebnisse des Würfelwurfs sollten angezeigt werden", diceResult2);

            int result1 = Integer.parseInt(diceResult1.getUserData("value").toString());
            int result2 = Integer.parseInt(diceResult2.getUserData("value").toString());
            int expectedSum = result1 + result2;

            Spatial sumDisplay = app.getGuiNode().getChild("DiceSum");
            assertEquals("Die Summe der Würfelergebnisse sollte korrekt angezeigt werden", expectedSum, Integer.parseInt(sumDisplay.getUserData("value").toString()));
        } else {
            throw new AssertionError("'RollDiceButton' ist kein Button-Objekt.");
        }
    }

    @Test
    // T031: UC-gameplay-05 - Überprüfen, ob die Würfel nach dem Wurf ausgegraut werden
    public void testGrayOutDiceAfterRoll() {
        Spatial rollDiceButton = app.getGuiNode().getChild("RollDiceButton");
        assertNotNull("Der 'Würfeln'-Button sollte sichtbar sein", rollDiceButton);

        if (rollDiceButton instanceof Button) {
            ((Button) rollDiceButton).click(); // Simuliert einen Würfelwurf

            Spatial diceDisplay = app.getGuiNode().getChild("DiceDisplay");
            assertNotNull("Die Würfelanzeige sollte nach dem Wurf sichtbar sein", diceDisplay);

            boolean isGrayedOut = diceDisplay.getUserData("grayedOut");
            assertTrue("Die Würfel sollten nach dem Wurf ausgegraut sein", isGrayedOut);
        } else {
            throw new AssertionError("'RollDiceButton' ist kein Button-Objekt.");
        }
    }

    @Test
    // T032: UC-gameplay-06 - Überprüfen, ob das Würfeln eines Paschs erkannt wird
    public void testDetectDouble() {
        Spatial rollDiceButton = app.getGuiNode().getChild("RollDiceButton");
        assertNotNull("Der 'Würfeln'-Button sollte sichtbar sein", rollDiceButton);

        if (rollDiceButton instanceof Button) {
            // Simuliert mehrere Würfe, um einen Pasch zu erkennen
            for (int i = 0; i < 10; i++) {
                ((Button) rollDiceButton).click();
                Spatial diceResult1 = app.getGuiNode().getChild("DiceResult1");
                Spatial diceResult2 = app.getGuiNode().getChild("DiceResult2");

                int result1 = Integer.parseInt(diceResult1.getUserData("value").toString());
                int result2 = Integer.parseInt(diceResult2.getUserData("value").toString());

                if (result1 == result2) {
                    Spatial doubleIndicator = app.getGuiNode().getChild("DoubleIndicator");
                    assertNotNull("Ein Pasch sollte angezeigt werden, wenn zwei identische Zahlen geworfen werden", doubleIndicator);
                    break;
                }
            }
        } else {
            throw new AssertionError("'RollDiceButton' ist kein Button-Objekt.");
        }
    }

    @Test
    // T033: UC-gameplay-06 - Überprüfen, ob der Spieler bei einem Pasch erneut würfeln darf
    public void testDoubleRoll() {
        Spatial rollDiceButton = app.getGuiNode().getChild("RollDiceButton");
        assertNotNull("Der 'Würfeln'-Button sollte sichtbar sein", rollDiceButton);

        if (rollDiceButton instanceof Button) {
            // Simuliert das Würfeln eines Paschs
            ((Button) rollDiceButton).click();
            Spatial diceResult1 = app.getGuiNode().getChild("DiceResult1");
            Spatial diceResult2 = app.getGuiNode().getChild("DiceResult2");

            int result1 = Integer.parseInt(diceResult1.getUserData("value").toString());
            int result2 = Integer.parseInt(diceResult2.getUserData("value").toString());

            if (result1 == result2) { // Überprüft, ob ein Pasch geworfen wurde
                Spatial rollAgainIndicator = app.getGuiNode().getChild("RollAgainIndicator");
                assertNotNull("Der Spieler sollte bei einem Pasch erneut würfeln dürfen", rollAgainIndicator);
            }
        } else {
            throw new AssertionError("'RollDiceButton' ist kein Button-Objekt.");
        }
    }

    @Test
    // T034: UC-gameplay-06 - Überprüfen, ob der Spieler nach dem dritten Pasch ins Gefängnis muss
    public void testTripleDoubleGulag() {
        int doubleCount = 0;

        for (int i = 0; i < 3; i++) {
            Spatial rollDiceButton = app.getGuiNode().getChild("RollDiceButton");
            assertNotNull("Der 'Würfeln'-Button sollte sichtbar sein", rollDiceButton);

            if (rollDiceButton instanceof Button) {
                ((Button) rollDiceButton).click();
                Spatial diceResult1 = app.getGuiNode().getChild("DiceResult1");
                Spatial diceResult2 = app.getGuiNode().getChild("DiceResult2");

                int result1 = Integer.parseInt(diceResult1.getUserData("value").toString());
                int result2 = Integer.parseInt(diceResult2.getUserData("value").toString());

                if (result1 == result2) {
                    doubleCount++;
                }

                if (doubleCount == 3) {
                    Spatial jailIndicator = app.getGuiNode().getChild("JailIndicator");
                    assertNotNull("Der Spieler sollte nach dem dritten Pasch ins Gefängnis gehen", jailIndicator);
                    break;
                }
            } else {
                throw new AssertionError("'RollDiceButton' ist kein Button-Objekt.");
            }
        }

        assertTrue("Der Spieler sollte drei Paschs geworfen haben", doubleCount == 3);
    }
    @Test
// T035: UC-gameplay-07 - Überprüfen, ob ein Spieler für Steuerfelder korrekt belastet wird
    public void testTaxFieldCharges() {
        Game game = new Game();
        PlayerHandler playerHandler = game.getPlayerHandler();
        Player activePlayer = playerHandler.getActivePlayer();
        assertNotNull("Es sollte einen aktiven Spieler geben", activePlayer);

        int initialBalance = activePlayer.getAccountBalance();

        activePlayer.moveToField(game.getGameBoard().getFieldById(4)); // ID 4: Steuerfeld "Diszi"
        game.getGameBoard().applyFieldEffect(activePlayer);

        int expectedBalance = initialBalance - 200; // Beispielsteuer: 200 €
        assertEquals("Der Spieler sollte für das Steuerfeld korrekt belastet werden", expectedBalance, activePlayer.getAccountBalance());
    }

    @Test
// T036: UC-gameplay-08 - Überprüfen, ob ein Spieler korrekt ins Gefängnis geschickt wird
    public void testGoToJailField() {
        Game game = new Game();
        PlayerHandler playerHandler = game.getPlayerHandler();
        Player activePlayer = playerHandler.getActivePlayer();
        assertNotNull("Es sollte einen aktiven Spieler geben", activePlayer);

        activePlayer.moveToField(game.getGameBoard().getFieldById(30)); // ID 30: Ab ins Gefängnis
        game.getGameBoard().applyFieldEffect(activePlayer);

        assertEquals("Der Spieler sollte ins Gefängnis geschickt werden", 10, activePlayer.getFieldId()); // ID 10: Gefängnis
    }

    @Test
// T037: UC-gameplay-09 - Überprüfen, ob ein Spieler bei "Frei Parken" keine Gebühren zahlt
    public void testFreeParking() {
        Game game = new Game();
        PlayerHandler playerHandler = game.getPlayerHandler();
        Player activePlayer = playerHandler.getActivePlayer();
        assertNotNull("Es sollte einen aktiven Spieler geben", activePlayer);

        int initialBalance = activePlayer.getAccountBalance();

        activePlayer.moveToField(game.getGameBoard().getFieldById(20)); // ID 20: Frei Parken
        game.getGameBoard().applyFieldEffect(activePlayer);

        assertEquals("Der Spieler sollte bei 'Frei Parken' keine Gebühren zahlen", initialBalance, activePlayer.getAccountBalance());
    }
}



