using EFlib;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Model;
using StubEF;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Reflection.PortableExecutable;
using Xunit;

namespace TestEF
{
    public class UniTestChampion
    {
        [Fact]
        public async Task AddChampion_Test()
        {
            // connection must be opened to use In-memory database
            var connection = new SqliteConnection("DataSource =:memory:");
            connection.Open();

            var options = new DbContextOptionsBuilder<SQLiteContext>().UseSqlite(connection).Options;

            using (var context = new SQLiteContext(options))
            {
                await context.Database.EnsureCreatedAsync(); //pour créer la base si elle n'existe pas déjà         

                // Arrange
                EFChampion champion = new EFChampion
                {
                    Name = "Champion 1",
                    Bio = "Bio Champion 1",
                    Icon = "aatrox_icon.jpg",
                    Class = ChampionClass.Assassin,

                    Characteristics = new List<EFCharacteristics> {
                            new EFCharacteristics { Name = "Attack Damage", Value = 60 },
                            new EFCharacteristics { Name = "Armor", Value = 38 },
                            new EFCharacteristics { Name = "Magic Resist", Value = 32 }
                    },

                    Skills = ImmutableHashSet.Create<EFSkill>(
                        new EFSkill { Name = "Skill 1", Description = "Desc Skill 1" },
                        new EFSkill { Name = "Skill 2", Description = "Desc Skill 2" }
                    ),

                    Skins = new ReadOnlyCollection<EFSkin>(new List<EFSkin> {
                    new EFSkin
                    {
                        Name = "Mecha Kingdoms Aatrox",
                        Description = "In a distant cyberfuture, the champion Aatrox becomes a symbol of ultimate power and glory...",
                        Icon = "aatrox_mecha_icon.jpg",
                        Price = 1350,
                        NameChampion = "Aatrox",
                        ImageId = Guid.NewGuid(),
                        Image = new EFLargeImage { Id = Guid.NewGuid(), Base64 = "aatrox_mecha_splash.jpg" }
                    } } ),

                    Image = new EFLargeImage { Id = Guid.NewGuid(), Base64 = "CheminDeMonChampion" }
                };
               
                context.Add(champion);
                await context.SaveChangesAsync();
          
                // Act
                await context.Champions.FirstOrDefaultAsync(c => c.Name == "Champion 1");

                // Assert
                Assert.NotNull(champion);
                Assert.Equal("Bio Champion 1", champion.Bio);
                Assert.Equal("aatrox_icon.jpg", champion.Icon);
                Assert.NotNull(champion.Characteristics);
                Assert.Equal(3, champion.Characteristics.Count);
                Assert.Equal(ChampionClass.Assassin, champion.Class);
                Assert.Single(champion.Skins);
                if (champion.Skins.Any())
                {
                    Assert.Equal("Mecha Kingdoms Aatrox", champion.Skins[0].Name);
                }
                Assert.Equal(2, champion.Skills.Count);
                Assert.Contains(champion.Skills, s => s.Name == "Skill 1");
                Assert.Contains(champion.Skills, s => s.Name == "Skill 2");
                Assert.Equal("CheminDeMonChampion", champion.Image.Base64);
            }
        }


        [Fact]
        public async Task GetChampion_Test()
        {
            //connection must be opened to use In-memory database
            var connection = new SqliteConnection("DataSource =:memory:");
            connection.Open();

            var options = new DbContextOptionsBuilder<SQLiteContext>().UseSqlite(connection).Options;

            using (var context = new StubEFChampions(options))
            {
                //context.Database.OpenConnection();
                await context.Database.EnsureCreatedAsync(); //pour créer la base si elle n'existe pas déjà

                var champs = context.Champions.SingleOrDefault(c => c.Name == "Akali");

                Assert.NotNull(champs);
                Assert.Equal("Akali", champs.Name);
            }
        }
    }



            /*
        [Fact]
        public void Modify_Test()
        {
            //connection must be opened to use In-memory database
            var connection = new SqliteConnection("DataSource=:memory:");
            connection.Open();

            var options = new DbContextOptionsBuilder<SQLiteContext>().UseSqlite(connection).Options;

            //prepares the database with one instance of the context
            using (var context = new StubEFChampions(options))
            {
                //context.Database.OpenConnection();
                context.Database.EnsureCreated();
/*
                Nounours chewie = new Nounours { Nom = "Chewbacca" };
                Nounours yoda = new Nounours { Nom = "Yoda" };
                Nounours ewok = new Nounours { Nom = "Ewok" };

                context.Nounours.Add(chewie);
                context.Nounours.Add(yoda);
                context.Nounours.Add(ewok);
                context.SaveChanges();
            }*/

        //uses another instance of the context to do the tests
        /*  using (var context = new StubEFChampions(options))
          {
              context.Database.EnsureCreated();

              string nameToFind = "ew";
              Assert.Equal(2, context.Champions.Where(n => n.Name.ToLower().Contains(nameToFind)).Count());
              nameToFind = "wo";
              Assert.Equal(1, context.Champions.Where(n => n.Name.ToLower().Contains(nameToFind)).Count());
              var ewok = context.Champions.Where(n => n.Name.ToLower().Contains(nameToFind)).First();
              ewok.Name = "Wicket";
              context.SaveChanges();
          }

          //uses another instance of the context to do the tests
          using (var context = new StubEFChampions(options))
          {
              context.Database.EnsureCreated();

              string nameToFind = "ew";
              Assert.Equal(1, context.Champions.Where(n => n.Name.ToLower().Contains(nameToFind)).Count());
              nameToFind = "wick";
              Assert.Equal(1, context.Champions.Where(n => n.Name.ToLower().Contains(nameToFind)).Count());
          }
      }*/
        /*
        [SetUp]
        public void Setup()
        {
        }


        [Test]
        public void TestGET()
        {
            //Arrange

            //Act
            var championResult = ChampionController.get();

            //Assert
            var objectResult = championResult as OkObjectResult;
            //vérifie que c’est un ok 200 et un objet
            Assert.IsNotNull(objectResult);

            var champions = objectResult?.Value as IEnumerable<ChampionDto>;
            Assert.IsNotNull(champions);

            Assert.AreEqual(champions.Count(), (await StubData.championsMgr.getItems(0, 5)).Count());
        }

        [Test]
        public void TestPOST()
        {
            //Arrange
            var championDto = new ChampionDto()
            {
                Name = "Darius"
            };

            //Act
            var championResult = await ChampionController.post(championDto);

            //Assert
            var objectResult = championResult as CreatedAtActionResult;
            Assert.IsNotNull(objectResult);

            var champions = objectResult?.Value as ChampionDto;
            Assert.IsNotNull(champions);

        }
       

    } */
    }