using TestingServerPartWabi.HelpsUserData;
using Supabase;
using TestingWabi.Models;
using static Supabase.Postgrest.Constants;
using Supabase.Postgrest.Responses;

namespace TestingWabi
{
    public class Tests
    {
        [Fact]
        public async void CheckCreatedClient()
        {
            Client sup = await InicializeSupabase.InitClient();

            Assert.NotNull(sup);
        }

        [Fact]
        public async void CheckSignInOfUser()
        {
            Client sup = await InicializeSupabase.InitClient();

            EnvReader.Load("..\\..\\..\\HelpsData\\data.env");
            string email = Environment.GetEnvironmentVariable("TEST_USER_EMAIL");
            string password = Environment.GetEnvironmentVariable("TEST_USER_PASSWORD");

            var user = await sup.Auth.SignIn(email, password);

            Assert.NotNull(user);
        }

        [Fact]
        public async void CheckSignOutOfUser()
        {
            Client sup = await InicializeSupabase.InitClient();

            EnvReader.Load("..\\..\\..\\HelpsData\\data.env");
            string email = Environment.GetEnvironmentVariable("TEST_USER_EMAIL");
            string password = Environment.GetEnvironmentVariable("TEST_USER_PASSWORD");

            var user = await sup.Auth.SignIn(email, password);
            var session = sup.Auth.CurrentSession;

            await sup.Auth.SignOut();
            session = sup.Auth.CurrentSession;

            Assert.Null(session);
        }

        [Fact]
        public async void CheckPoliciesAllRead()
        {
            Client sup = await InicializeSupabase.InitClient();

            int coutntRow = 0;

            bool equels = false;

            try
            {
                coutntRow = await sup.From<Basket>().Count(CountType.Exact);
                equels = !(coutntRow == 0);
            }
            catch
            {
                equels = false;
            }

            Assert.True(equels);
        }

        [Fact]
        public async void CheckPoliciesThereIsNoAccess()
        {
            Client sup = await InicializeSupabase.InitClient();

            EnvReader.Load("..\\..\\..\\HelpsData\\data.env");
            string email = Environment.GetEnvironmentVariable("TEST_USER_EMAIL");
            string password = Environment.GetEnvironmentVariable("TEST_USER_PASSWORD");

            var user = await sup.Auth.SignIn(email, password);

            Unit unit = new Unit()
            {
                UnitName = "Öèôðà",
                ShortName = "öèôð.",
                RealNumber = true
            };

            bool callException = false;

            try
            {
                ModeledResponse<Unit> response = await sup.From<Unit>().Insert(unit);
            }
            catch (Supabase.Postgrest.Exceptions.PostgrestException)
            {
                callException = true;
            }

            await sup.Auth.SignOut();

            Assert.True(callException);
        }

        [Fact]
        public async void CheckPoliciesInsertWithAuthWithOutSignIn()
        {
            Client sup = await InicializeSupabase.InitClient();

            bool callException = false;

            Basket basket = new Basket()
            {
                User = "bbfa8cd2-9862-4474-8389-a054c5fad1fa",
                Product = "b6ab37a5-8304-4e1a-9691-79ba50473502",
                Status = true,
                Count = 1
            };

            try
            {
                ModeledResponse<Basket> response = await sup.From<Basket>().Insert(basket);
            }
            catch (Supabase.Postgrest.Exceptions.PostgrestException)
            {
                callException = true;
            }

            Assert.True(callException);
        }

        [Fact]
        public async void CheckPoliciesInsertWithAuthWithSignIn()
        {
            Client sup = await InicializeSupabase.InitClient();

            EnvReader.Load("..\\..\\..\\HelpsData\\data.env");
            string email = Environment.GetEnvironmentVariable("TEST_USER_EMAIL");
            string password = Environment.GetEnvironmentVariable("TEST_USER_PASSWORD");

            var user = await sup.Auth.SignIn(email, password);

            bool callException = true;

            Basket basket = new Basket()
            {
                User = "5b464923-3799-4630-ab75-b091a701ac37",
                Product = "b6ab37a5-8304-4e1a-9691-79ba50473502",
                Status = true,
                Count = 1
            };

            try
            {
                ModeledResponse<Basket> response = await sup.From<Basket>().Insert(basket);
            }
            catch (Supabase.Postgrest.Exceptions.PostgrestException)
            {
                callException = false;
            }

            await sup.Auth.SignOut();

            Assert.True(callException);
        }

        [Fact]
        public async void CheckPoliciesUpdateAllUsers()
        {
            Client sup = await InicializeSupabase.InitClient();

            bool callException = false;

            ModeledResponse<Basket> response = await sup.From<Basket>()
                    .Where(x => x.User == "5b464923-3799-4630-ab75-b091a701ac37")
                    .Set(x => x.Status, false)
                    .Update();

            int coutntRow = await sup.From<Basket>()
                .Where(x => x.Status == false && x.User == "5b464923-3799-4630-ab75-b091a701ac37")
                .Count(CountType.Exact);

            if (coutntRow > 0)
            {
                callException = true;
            }

            Assert.True(callException);
        }

        [Fact]
        public async void CheckPoliciesDeleteWithAuthWithOutSignIn()
        {
            Client sup = await InicializeSupabase.InitClient();

            if (sup.Auth.CurrentSession != null)
            {
                await sup.Auth.SignOut();
            }

            bool callException = false;

            await sup.From<Basket>()
                .Where(x => x.Status == true && x.User == "5b464923-3799-4630-ab75-b091a701ac37")
                .Delete();

            int coutntRow = await sup.From<Basket>()
               .Where(x => x.Status == true && x.User == "5b464923-3799-4630-ab75-b091a701ac37")
               .Count(CountType.Exact);

            if (coutntRow == 0)
            {
                callException = true;
            }

            Assert.True(callException);
        }

        [Fact]
        public async void CheckPoliciesDeleteWithAuthWithSignIn()
        {
            Client sup = await InicializeSupabase.InitClient();

            EnvReader.Load("..\\..\\..\\HelpsData\\data.env");
            string email = Environment.GetEnvironmentVariable("TEST_USER_EMAIL");
            string password = Environment.GetEnvironmentVariable("TEST_USER_PASSWORD");

            var user = await sup.Auth.SignIn(email, password);

            bool callException = false;

            var session = sup.Auth.CurrentSession;

            await sup.From<Basket>()
            .Where(x => x.Status == true && x.User == session.User.Id)
            .Delete();

            await sup.Auth.SignOut();

            int coutntRow = await sup.From<Basket>()
                .Where(x => x.Status == true && x.User == session.User.Id)
                .Count(CountType.Exact);

            if (coutntRow == 0)
            {
                callException = true;
            }

            Assert.True(callException);
        }

        [Fact]
        public async void CheckPoliciesUpdateWithAuthWithOutSignIn()
        {
            Client sup = await InicializeSupabase.InitClient();

            bool callException = false;

            ModeledResponse<User> response = await sup.From<User>()
                    .Where(x => x.Id == "5b464923-3799-4630-ab75-b091a701ac37")
                    .Set(x => x.Theme, 2)
                    .Update();

            int coutntRow = await sup.From<User>()
                .Where(x => x.Id == "5b464923-3799-4630-ab75-b091a701ac37" &&  x.Theme == 2)
                .Count(CountType.Exact);

            if (coutntRow == 0)
            {
                callException = true;
            }

            Assert.True(callException);
        }

        [Fact]
        public async void CheckPoliciesUpdateWithAuthWithSignIn()
        {
            Client sup = await InicializeSupabase.InitClient();

            EnvReader.Load("..\\..\\..\\HelpsData\\data.env");
            string email = Environment.GetEnvironmentVariable("TEST_USER_EMAIL");
            string password = Environment.GetEnvironmentVariable("TEST_USER_PASSWORD");

            var user = await sup.Auth.SignIn(email, password);

            var session = sup.Auth.CurrentSession;

            bool callException = false;

            ModeledResponse<User> response = await sup.From<User>()
                    .Where(x => x.Id == session.User.Id)
                    .Set(x => x.Theme, 1)
                    .Update();

            int coutntRow = await sup.From<User>()
                .Where(x => x.Id == session.User.Id && x.Theme == 1)
                .Count(CountType.Exact);

            await sup.Auth.SignOut();

            if (coutntRow > 0)
            {
                callException = true;
            }

            Assert.True(callException);
        }

        [Fact]
        public async void CheckLimitredValueUserThemeAndPolic()
        {
            Client sup = await InicializeSupabase.InitClient();

            EnvReader.Load("..\\..\\..\\HelpsData\\data.env");
            string email = Environment.GetEnvironmentVariable("TEST_USER_EMAIL");
            string password = Environment.GetEnvironmentVariable("TEST_USER_PASSWORD");

            var user = await sup.Auth.SignIn(email, password);

            var session = sup.Auth.CurrentSession;

            bool callException = false;

            try
            {
                ModeledResponse<User> response = await sup.From<User>()
                    .Where(x => x.Id == session.User.Id)
                    .Set(x => x.Theme, 4)
                    .Update();

                int coutntRow = await sup.From<User>()
                    .Where(x => x.Id == session.User.Id && x.Theme == 4)
                    .Count(CountType.Exact);

                await sup.Auth.SignOut();

                if (coutntRow > 0)
                {
                    callException = true;
                }
            }
            catch (Supabase.Postgrest.Exceptions.PostgrestException) 
            {
                callException = true;
            }

            Assert.True(callException);
        }
    }
}