using CoreLibrary.Core;
using CoreLibrary.Events;
using CoreLibrary.Joueurs;
using System.Reflection;
using Xunit;

namespace UnitTesting
{
    public class JoueurUT
    {
        [Fact]
        public void TestConstructeur1Valide()
        {
            string nom = "toto";

            Joueur joueur = new Joueur(nom);


            Assert.Equal(nom, joueur.Nom);
            Assert.Equal(0, joueur.NbCoutTotal);
            Assert.Equal(0, joueur.NbPartieGagnee);
            Assert.Equal(0, joueur.NbPartieEgalite);
            Assert.Equal(0, joueur.NbPartiePerdue);
        }


        [Fact]
        public void TestConstructeur2Valide()
        {
            string nom = "Bob";
            int nbCoutTotal = 10;
            int nbPartieGagnee = 5;
            int nbPartieEgalite = 2;
            int nbPartiePerdue = 3;

            Joueur joueur = new Joueur(nom, nbCoutTotal, nbPartieGagnee, nbPartieEgalite, nbPartiePerdue);

            Assert.Equal(nom, joueur.Nom);
            Assert.Equal(nbCoutTotal, joueur.NbCoutTotal);
            Assert.Equal(nbPartieGagnee, joueur.NbPartieGagnee);
            Assert.Equal(nbPartieEgalite, joueur.NbPartieEgalite);
            Assert.Equal(nbPartiePerdue, joueur.NbPartiePerdue);
        }

        [Fact]
        public void TestEvenement()
        {
            Code code = new Code([new Jeton(Couleur.ROUGE), new Jeton(Couleur.BLEU), new Jeton(Couleur.JAUNE), new Jeton(Couleur.VERT)]);
            Code? codeEvenement = null;

            Joueur j = new Joueur("Céleste");
            j.JouerCode += (Object? sender, JouerCodeEventArgs e) => codeEvenement = e.Code;

            j.Code(code);

            Assert.NotNull(codeEvenement);
            Assert.Equal(code, codeEvenement);
        }

        [Fact]
        public void JoueurQuandJouerCode()
        {
            Code code = new Code(4);
            code.AjouterJeton(new Jeton(Couleur.ROUGE));
            code.AjouterJeton(new Jeton(Couleur.BLANC));
            code.AjouterJeton(new Jeton(Couleur.BLEU));
            code.AjouterJeton(new Jeton(Couleur.NOIR));

            Code? codeEvenement = null;

            Joueur joueur = new Joueur("Céleste");
            joueur.JouerCode += (Object? sender, JouerCodeEventArgs e) => codeEvenement = e.Code;

            Type type = typeof(Joueur);
            MethodInfo? methodInfo = type.GetMethod("QuandJouerCode", BindingFlags.NonPublic | BindingFlags.Instance);
            Assert.NotNull(methodInfo);
            methodInfo.Invoke(joueur, [code]);

            Assert.NotNull(codeEvenement);
            Assert.Equal(code, codeEvenement);
        }

        [Fact]
        public void JoueurQuandJouerCodeSansBranchement()
        {
            Joueur joueur = new Joueur("Pauline");
            Code code = new Code(4);
            code.AjouterJeton(new Jeton(Couleur.ROUGE));
            code.AjouterJeton(new Jeton(Couleur.BLANC));
            code.AjouterJeton(new Jeton(Couleur.BLEU));
            code.AjouterJeton(new Jeton(Couleur.NOIR));

            Assert.Null(Record.Exception(() => joueur.Code(code)));
        }
    }
}
