package com.ghost.technic.server.card;

import com.ghost.technic.server.Player;
import com.ghost.technic.server.board.Flank;
import com.ghost.technic.server.card.effect.impl.BarristerJoyaAbility;
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 com.ghost.technic.server.game.event.EventType;
import com.ghost.technic.server.game.event.GameEvent;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;

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

class BarristerJoyaTest {

    GameActionService gameActionService;
    Player you;
    Player opponent;
    CreatureCard joya;
    CreatureCard enemyBadPenny;
    CreatureCard enemyRadPenny;

    @BeforeEach
    void setUp() {
        gameActionService = new GameActionService(new GameState(new EventBus()));
        you = Player.builder().name("You").build();
        opponent = Player.builder().name("Opponent").build();

        joya = CreatureCard.builder()
                .name("Barrister Joya")
                .house(House.SANCTUM)
                .power(4)
                .armor(2)
                .abilities(List.of(new BarristerJoyaAbility()))
                .build();

        enemyBadPenny = CreatureCard.builder()
                .name("Bad Penny")
                .house(House.SHADOWS)
                .power(1)
                .armor(0)
                .build();

        enemyRadPenny = CreatureCard.builder()
                .name("Rad Penny")
                .house(House.SHADOWS)
                .power(1)
                .armor(0)
                .build();

        GameState state = gameActionService.getGameState();
        state.setOwner(joya, you);
        state.setOwner(enemyBadPenny, opponent);
        state.setOwner(enemyRadPenny, opponent);
    }

    @Test
    void testJoyaBlocksEnemyReapButNotFriendly() {
        var friendlyYurk = CreatureCard.builder()
                .name("Yurk")
                .house(House.DIS)
                .power(4)
                .armor(0)
                .build();

        gameActionService.getGameState().setOwner(friendlyYurk, you);

        gameActionService.playCreature(you, joya, Flank.LEFT);
        gameActionService.playCreature(you, friendlyYurk, Flank.RIGHT);
        gameActionService.playCreature(opponent, enemyBadPenny, Flank.RIGHT);

        enemyBadPenny.setReady(true);
        gameActionService.reap(enemyBadPenny, opponent);
        assertEquals(0, opponent.getAmber(), "Enemy should NOT reap while Joya is in play");

        friendlyYurk.setReady(true);
        gameActionService.reap(friendlyYurk, you);
        assertEquals(1, you.getAmber(), "Friendly should reap normally");
    }

    @Test
    void testEnemyPlayedAfterJoyaCannotReap() {
        gameActionService.playCreature(you, joya, Flank.LEFT);
        gameActionService.playCreature(opponent, enemyBadPenny, Flank.RIGHT);

        enemyBadPenny.setReady(true);
        gameActionService.reap(enemyBadPenny, opponent);
        assertEquals(0, opponent.getAmber(), "Enemy creature played after Joya should not reap");
    }

    @Test
    void testMultipleEnemyCreaturesCannotReap() {
        gameActionService.playCreature(you, joya, Flank.LEFT);
        gameActionService.playCreature(opponent, enemyBadPenny, Flank.LEFT);
        gameActionService.playCreature(opponent, enemyRadPenny, Flank.RIGHT);

        enemyBadPenny.setReady(true);
        enemyRadPenny.setReady(true);

        gameActionService.reap(enemyBadPenny, opponent);
        gameActionService.reap(enemyRadPenny, opponent);
        assertEquals(0, opponent.getAmber(), "No enemy should reap while Joya is active");
    }

    @Test
    void testEnemyCanReapAfterJoyaDestroyed() {
        gameActionService.playCreature(you, joya, Flank.LEFT);
        gameActionService.playCreature(opponent, enemyBadPenny, Flank.RIGHT);

        // Destroy Joya
        GameEvent destroyEvent = new GameEvent(EventType.CREATURE_DESTROYED, Map.of("creature", joya));
        gameActionService.getEventBus().publish(destroyEvent);

        enemyBadPenny.setReady(true);
        gameActionService.reap(enemyBadPenny, opponent);
        assertEquals(1, opponent.getAmber(), "Enemy should reap after Joya is destroyed");
    }
}
