package com.ghost.technic.server.card;

import com.ghost.technic.server.card.effect.impl.DexusTriggeredAbility;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.ghost.technic.server.Player;
import com.ghost.technic.server.board.Flank;
import com.ghost.technic.server.card.misc.House;
import com.ghost.technic.server.card.playable.usable.impl.CreatureCard;
import com.ghost.technic.server.game.GameActionService;
import com.ghost.technic.server.game.GameState;
import com.ghost.technic.server.game.event.EventBus;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

class DexusTest {

    GameActionService gameActionService;
    Player alice; // controller of Dexus
    Player bob;   // opponent
    CreatureCard dexus;

    @BeforeEach
    void setUp() {
        gameActionService = new GameActionService(new GameState(new EventBus()));
        alice = Player.builder().name("Alice").build();
        bob = Player.builder().name("Bob").build();

        dexus = CreatureCard.builder()
                .name("Dexus")
                .house(House.DIS)
                .power(3)
                .armor(1)
                .abilities(List.of(new DexusTriggeredAbility()))
                .build();

        gameActionService.getGameState().setPlayers(alice, bob);
        gameActionService.getGameState().setOwner(dexus, alice);
        gameActionService.playCreature(alice, dexus, Flank.LEFT);
    }

    private CreatureCard makeCreature(String name, House house) {
        return CreatureCard.builder()
                .name(name)
                .house(house)
                .power(2)
                .armor(0)
                .build();
    }

    @Test
    void friendlyCreaturePlayedOnRightFlank_shouldNotLoseAmber() {
        CreatureCard friendly = makeCreature("Friendly Minion", House.DIS);
        gameActionService.getGameState().setOwner(friendly, alice);
        alice.setAmber(3);

        gameActionService.playCreature(alice, friendly, Flank.RIGHT);

        assertEquals(3, alice.getAmber(), "Alice should not lose amber when playing to right flank");
    }

    @Test
    void friendlyCreaturePlayedOnLeftFlank_shouldNotLoseAmber() {
        CreatureCard friendly = makeCreature("Friendly Minion", House.DIS);
        gameActionService.getGameState().setOwner(friendly, alice);
        alice.setAmber(3);

        gameActionService.playCreature(alice, friendly, Flank.LEFT);

        assertEquals(3, alice.getAmber(), "Alice should not lose amber when playing to left flank");
    }

    @Test
    void enemyCreaturePlayedOnRightFlank_shouldLoseAmber() {
        CreatureCard enemy = makeCreature("Enemy Minion", House.SANCTUM);
        gameActionService.getGameState().setOwner(enemy, bob);
        bob.setAmber(2);

        gameActionService.playCreature(bob, enemy, Flank.RIGHT);

        assertEquals(1, bob.getAmber(), "Bob should lose 1 amber for playing to right flank");
    }

    @Test
    void enemyCreaturePlayedOnLeftFlank_shouldLoseAmberDueToBeingTheOnlyOne() {
        CreatureCard enemy = makeCreature("Enemy Minion", House.SANCTUM);
        gameActionService.getGameState().setOwner(enemy, bob);
        bob.setAmber(2);

        gameActionService.playCreature(bob, enemy, Flank.LEFT);

        assertEquals(1, bob.getAmber(), "Bob should lose amber even for playing to left flank because there's no other creature");
    }

    @Test
    void enemyPlaysTwoCreaturesToRightFlank_shouldLoseAmberTwice() {
        CreatureCard e1 = makeCreature("Righty1", House.SANCTUM);
        CreatureCard e2 = makeCreature("Righty2", House.SANCTUM);
        gameActionService.getGameState().setOwner(e1, bob);
        gameActionService.getGameState().setOwner(e2, bob);
        bob.setAmber(3);

        gameActionService.playCreature(bob, e1, Flank.RIGHT);
        assertEquals(2, bob.getAmber(), "Bob should lose 1 amber for first creature being played");

        gameActionService.playCreature(bob, e2, Flank.RIGHT);
        assertEquals(1, bob.getAmber(), "Bob should lose second amber for a creature being played on the right flank");
    }

    @Test
    void enemyPlaysTwoCreaturesToLeftFlank_shouldLoseAmberForTheFirstCreature() {
        CreatureCard e1 = makeCreature("Lefty1", House.SANCTUM);
        CreatureCard e2 = makeCreature("Lefty2", House.SANCTUM);
        gameActionService.getGameState().setOwner(e1, bob);
        gameActionService.getGameState().setOwner(e2, bob);
        bob.setAmber(3);

        gameActionService.playCreature(bob, e1, Flank.LEFT);
        assertEquals(2, bob.getAmber(), "Bob should lose 1 amber due to it being the only creature");

        gameActionService.playCreature(bob, e2, Flank.LEFT);
        assertEquals(2, bob.getAmber(), "Bob should not lose amber for left-flank plays");
    }
}
