package it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events;

import it.polimi.ingsw.gc14.Model.Cards.Building.EffectType;
import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.Shaman;
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.EventType;
import it.polimi.ingsw.gc14.Model.Player;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Arrays;

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

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Arrays;

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

class ShamanicRitualTest {

    @Test
    @DisplayName("Testing constructor")
    void testConstructor() {
        // Gli attributi di ShamanicRitual era e EventType vengono testati in EventCardTest.

        // Gli attributi prestigeToAdd e prestigeToRemove non possono essere testati singolarmente in quanto non hanno metodi getter
        // Ne viene testato il corretto funzionamento indirettamente attraverso applyEffect.

        // Come conseguenza finale, non può essere testato il costruttore di ShamanicRitual
    }

    @Test
    @DisplayName("No edge case test")
    void applyEvent() {
        Player p1 = new Player("Marco");
        Player p2 = new Player("Luca");

        ArrayList<Player> players = new ArrayList<>(Arrays.asList(p1, p2));

        new Shaman(1, 3).insert(p1);
        new Shaman(1, 1).insert(p2);

        ShamanicRitual ritual = new ShamanicRitual(1, 10, 5);
        ritual.activateEvent(players);

        assertEquals(10, p1.getPrestigeValue());
        assertEquals(-5, p2.getPrestigeValue());
    }

    @Test
    @DisplayName("All players have the same icons")
    void applyEvent2() {
        Player p1 = new Player("Marco");
        Player p2 = new Player("Luca");

        ArrayList<Player> players = new ArrayList<>(Arrays.asList(p1, p2));

        new Shaman(1, 3).insert(p1);
        new Shaman(1, 3).insert(p2);

        ShamanicRitual ritual = new ShamanicRitual(1, 10, 5);
        ritual.activateEvent(players);

        assertEquals(5, p1.getPrestigeValue());
        assertEquals(5, p2.getPrestigeValue());
    }

    @Test
    @DisplayName("Two players have the highest amount of icons")
    void applyEvent3() {
        Player p1 = new Player("Marco");
        Player p2 = new Player("Luca");
        Player p3 = new Player("Giacomo");


        ArrayList<Player> players = new ArrayList<>(Arrays.asList(p1, p2, p3));

        new Shaman(1, 3).insert(p1);
        new Shaman(1, 3).insert(p2);
        new Shaman(1, 2).insert(p3);


        ShamanicRitual ritual = new ShamanicRitual(1, 10, 5);
        ritual.activateEvent(players);

        assertEquals(10, p1.getPrestigeValue());
        assertEquals(10, p2.getPrestigeValue());
        assertEquals(-5, p3.getPrestigeValue());
    }

    @Test
    @DisplayName("p3 has building 2")
    void applyEvent4() {
        Player p1 = new Player("Marco");
        Player p2 = new Player("Luca");
        Player p3 = new Player("Giacomo");


        ArrayList<Player> players = new ArrayList<>(Arrays.asList(p1, p2, p3));

        new Shaman(1, 3).insert(p1);
        new Shaman(1, 3).insert(p2);
        new Shaman(1, 2).insert(p3);

        BuildingCard bc1 = new BuildingCard(2,1,5,5);
        p3.addFood(5);
        bc1.buy(p3);

        ShamanicRitual ritual = new ShamanicRitual(1, 10, 5);
        ritual.activateEvent(players);

        assertEquals(10, p1.getPrestigeValue());
        assertEquals(10, p2.getPrestigeValue());
        assertEquals(0, p3.getPrestigeValue());
    }

    @Test
    @DisplayName("p1 has building 5")
    void applyEvent5() {
        Player p1 = new Player("Marco");
        Player p2 = new Player("Luca");


        ArrayList<Player> players = new ArrayList<>(Arrays.asList(p1, p2));

        new Shaman(1, 2).insert(p1);
        new Shaman(1, 3).insert(p2);

        BuildingCard bc1 = new BuildingCard(5,1,5,5);
        p1.addFood(5);
        bc1.buy(p1);

        ShamanicRitual ritual = new ShamanicRitual(1, 10, 5);
        ritual.activateEvent(players);

        assertEquals(10, p1.getPrestigeValue());
        assertEquals(-5, p2.getPrestigeValue());
    }

    @Test
    @DisplayName("p1 has building 6")
    void applyEvent6() {
        Player p1 = new Player("Marco");
        Player p2 = new Player("Luca");


        ArrayList<Player> players = new ArrayList<>(Arrays.asList(p1, p2));

        new Shaman(1, 3).insert(p1);
        new Shaman(1, 1).insert(p2);

        BuildingCard b = new BuildingCard(6, 1, 5, 1);
        p1.addFood(5);
        b.buy(p1);

        ShamanicRitual ritual = new ShamanicRitual(1, 10, 5);
        ritual.activateEvent(players);

        assertEquals(20, p1.getPrestigeValue());
        assertEquals(-5, p2.getPrestigeValue());
    }

    @Test
    @DisplayName("p1 has building 6 but p2 has same icons")
    void applyEvent7() {
        Player p1 = new Player("Marco");
        Player p2 = new Player("Luca");
        Player p3 = new Player("Giacomo");


        ArrayList<Player> players = new ArrayList<>(Arrays.asList(p1, p2, p3));

        new Shaman(1, 3).insert(p1);
        new Shaman(1, 3).insert(p2);
        new Shaman(1, 1).insert(p3);

        BuildingCard b = new BuildingCard(6, 1, 5, 1);
        p1.addFood(5);
        b.buy(p1);

        ShamanicRitual ritual = new ShamanicRitual(1, 10, 5);
        ritual.activateEvent(players);

        assertEquals(10, p1.getPrestigeValue());
        assertEquals(10, p2.getPrestigeValue());
        assertEquals(-5, p3.getPrestigeValue());
    }

    @Test
    @DisplayName("Clone testing")
    void cloneTest() {
        int era = 1;
        int prestigeToAdd = 10;
        int prestigeToRemove = 5;

        ShamanicRitual sr1 = new ShamanicRitual(era, prestigeToAdd,prestigeToRemove);
        ShamanicRitual sr2 = (ShamanicRitual) sr1.clone();

        assertEquals(1, sr2.getEra());
        assertEquals(EventType.SHAMANIC_RITUAL, sr2.getType());
        assertEquals(prestigeToAdd, sr2.prestigeToAdd);
        assertEquals(prestigeToRemove, sr2.prestigeToRemove);

    }

    @Test
    @DisplayName("ToString testing")
    void toStringTest() {
        ShamanicRitual sr1 = new ShamanicRitual(1, 5,2);

        assertEquals("Era:1, SHAMANIC_RITUAL", sr1.toString());
    }
}