package it.polimi.ingsw.gc14.Model.Cards.Building.Effects;

import it.polimi.ingsw.gc14.Model.Cards.Building.EffectType;
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType;
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.Artist;
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.Hunter;
import it.polimi.ingsw.gc14.Model.Player;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType.ARTIST;
import static it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType.HUNTER;
import static org.junit.jupiter.api.Assertions.*;

class Building11Test {

    @Test
    @DisplayName("Testing constructor")
    void testConstructor() {
        int era = 1;
        int price = 10;
        int prestigeValue = 5;
        CharacterType ct = CharacterType.ARTIST;
        int pm = 5;

        Building11 b0 = new Building11(era, price, prestigeValue, ct, pm);

        assertEquals(EffectType.FINAL, b0.getEffectType());
        assertEquals(11, b0.getEffectId());
        assertEquals(ct, b0.getIcon());
        assertEquals(pm, b0.getPrestigeMul());
    }

    @Test
    @DisplayName("Testing clone method")
    void testClone() {
        int effectID = 11;
        EffectType effectType = EffectType.FINAL;
        int era = 1;
        int price = 1;
        int prestigeValue = 1;
        CharacterType ct = CharacterType.ARTIST;
        int pm = 5;
        Building11 b0 = new Building11(era, price, prestigeValue, ct, pm);

        Building11 b1 = (Building11) b0.clone();

        assertEquals(effectID, b1.getEffectId());
        assertEquals(effectType, b1.getEffectType());
        assertEquals(era, b1.getEra());
        assertEquals(price, b1.getPrice());
        assertEquals(prestigeValue, b1.getPrestigeValue());
        assertEquals(ct, b0.getIcon());
        assertEquals(pm, b0.getPrestigeMul());
    }

    @Test
    void applyEffectBuyWithoutFood() {

        Player p1 = new Player("Xiaomi");
        Building11 b1 = new Building11(2, 10, 1, ARTIST, -3);
        Artist a1 = new Artist(2);
        b1.buy(p1);
        assertFalse(b1.buy(p1));
        p1.artists.add(a1);

        assertThrows(IllegalArgumentException.class, () -> {
            b1.applyEffect(p1);
        });
        p1.addFood(b1.getPrice());
        b1.buy(p1);
        b1.applyEffect(p1);
        assertEquals(-3, p1.getPrestigeValue());
    }

    @Test
    void applyEffectWithTwoCards() {
        Player p2 = new Player("Giacomo");
        Building11 b2 = new Building11(2, 10, 1, ARTIST, 4);
        Artist a2 = new Artist(2);
        Artist a3 = new Artist(2);
        p2.addFood(b2.getPrice());
        b2.buy(p2);
        p2.artists.add(a2);
        p2.artists.add(a3);


        b2.applyEffect(p2);
        assertEquals(8, p2.getPrestigeValue());
    }

    @Test
    void applyEffectTwoPlayersBuyTheSameCard() {
        Player p3 = new Player("AAAAAAAAAA");
        Player p4 = new Player("BBBBBBBBBB");
        Building11 b3 = new Building11(1, 15, 1, HUNTER, 5);
        p3.addFood(b3.getPrice());
        assertTrue(b3.buy(p3));
        p4.addFood(b3.getPrice());
        assertEquals(false, b3.buy(p4));
    }


    @Test
    void applyEffectApplyEffectWithoutBuyingFirst() {
        Player p5 = new Player("DRTFGBHJN");
        Building11 b4 = new Building11(3, 10, 1, ARTIST, 4);
        assertThrows(IllegalArgumentException.class, () -> {
            b4.applyEffect(p5);
        });
    }
}