using System;
using Xunit;
using Newtonsoft.Json.Linq;
using FluentAssertions;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Collections.Concurrent;

namespace raven_integration
{

    public class WidgetLists
    {



 /// <summary>
        /// 
        /// </summary>
        [Fact]
        public async void PickListSortByFieldAscendingWorks()
        {

            var WidgetNameStart = Util.Uniquify("PickListSortByFieldAscendingWorks");

            //CREATE 3 TEST WIDGETS TO TEST ORDER
            long FirstInOrderWidgetId = 0;
            long SecondInOrderWidgetId = 0;
            long ThirdInOrderWidgetId = 0;

            dynamic w = new JObject();
            w.name = Util.Uniquify(WidgetNameStart);
            w.startDate = DateTime.Now;
            w.endDate = DateTime.Now.AddHours(1);

            ApiResponse a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString());
            Util.ValidateDataReturnResponseOk(a);
            FirstInOrderWidgetId = a.ObjectResponse["data"]["id"].Value<long>();

            w = new JObject();
            w.name = Util.Uniquify(WidgetNameStart);
            w.startDate = DateTime.Now.AddHours(1);
            w.endDate = DateTime.Now.AddHours(2);
            a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString());
            Util.ValidateDataReturnResponseOk(a);
            SecondInOrderWidgetId = a.ObjectResponse["data"]["id"].Value<long>();

            w = new JObject();
            w.name = Util.Uniquify(WidgetNameStart);
            w.startDate = DateTime.Now.AddHours(2);
            w.endDate = DateTime.Now.AddHours(3);
            a = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w.ToString());
            Util.ValidateDataReturnResponseOk(a);
            ThirdInOrderWidgetId = a.ObjectResponse["data"]["id"].Value<long>();


            //CREATE FILTER
            dynamic d = new JObject();
            d.name = Util.Uniquify(WidgetNameStart);
            d["public"] = true;
            d.listKey = "widget";

            //FILTER IN BY NAME FOR TESTING THIS RUN ONLY
            dynamic dfilter = new JArray();
            //name starts with filter to constrict to widgets that this test block created only
            dynamic DataFilterNameStart = new JObject();
            DataFilterNameStart.fld = "name";
            DataFilterNameStart.op = Util.OpStartsWith;
            DataFilterNameStart.value = WidgetNameStart;
            dfilter.Add(DataFilterNameStart);
            d.filter = dfilter.ToString();

            //SORT ORDER ###################
            dynamic dsortarray = new JArray();
            dynamic dsort = new JObject();
            dsort.fld = "startdate";
            dsort.dir = "+";
            dsortarray.Add(dsort);
            d.sort = dsortarray.ToString();

            a = await Util.PostAsync("DataFilter", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString());
            Util.ValidateDataReturnResponseOk(a);

            long DataFilterId = a.ObjectResponse["data"]["id"].Value<long>();

            //NOW FETCH WIDGET LIST WITH FILTER
            a = await Util.GetAsync($"Widget/picklist?Offset=0&Limit=999&DataFilterId={DataFilterId.ToString()}", await Util.GetTokenAsync("manager", "l3tm3in"));
            Util.ValidateDataReturnResponseOk(a);
            Util.ValidateHTTPStatusCode(a, 200);

            //assert contains exactly 3 records
            ((JArray)a.ObjectResponse["data"]).Count.Should().Be(3);

            //assert the order returned
            a.ObjectResponse["data"][0]["id"].Value<long>().Should().Be(FirstInOrderWidgetId);
            a.ObjectResponse["data"][1]["id"].Value<long>().Should().Be(SecondInOrderWidgetId);
            a.ObjectResponse["data"][2]["id"].Value<long>().Should().Be(ThirdInOrderWidgetId);


            a = await Util.DeleteAsync("Widget/" + FirstInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"));
            Util.ValidateHTTPStatusCode(a, 204);

            a = await Util.DeleteAsync("Widget/" + SecondInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"));
            Util.ValidateHTTPStatusCode(a, 204);

            a = await Util.DeleteAsync("Widget/" + ThirdInOrderWidgetId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"));
            Util.ValidateHTTPStatusCode(a, 204);

            //DELETE DATAFILTER
            a = await Util.DeleteAsync("DataFilter/" + DataFilterId.ToString(), await Util.GetTokenAsync("manager", "l3tm3in"));
            Util.ValidateHTTPStatusCode(a, 204);

        }


        /// <summary>
        /// 
        /// </summary>       
        [Fact]
        public async void PickListSearchRouteShouldWorkAsExpected()
        {
            //CREATE
            dynamic d = new JObject();
            d.name = Util.Uniquify("Soft PickListSearchRouteShouldWorkAsExpected");
            d.created = DateTime.Now.ToString();
            d.dollarAmount = 1.11m;
            d.active = true;
            d.roles = 0;

            ApiResponse r1 = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), d.ToString());
            Util.ValidateDataReturnResponseOk(r1);

            //Get all
            ApiResponse a = await Util.GetAsync("Widget/picklist?Offset=2&Limit=3&q=%25of%25", await Util.GetTokenAsync("InventoryLimited"));
            Util.ValidateDataReturnResponseOk(a);
            Util.ValidateHTTPStatusCode(a, 200);
            ((JArray)a.ObjectResponse["data"]).Count.Should().BeGreaterThan(0);
        }


        /// <summary>
        /// Paging test
        /// </summary>       
        [Fact]
        public async void PagingShouldWorkAsExpected()
        {
            //Get all
            ApiResponse a = await Util.GetAsync("Widget/listwidgets?Offset=2&Limit=3", await Util.GetTokenAsync("manager", "l3tm3in"));
            Util.ValidateDataReturnResponseOk(a);
            Util.ValidateHTTPStatusCode(a, 200);

            //assert aAll contains at least two records
            ((JArray)a.ObjectResponse["data"]).Count.Should().Be(3);

            JObject jp = (JObject)a.ObjectResponse["paging"];
            jp["count"].Value<long>().Should().BeGreaterThan(5);
            jp["offset"].Value<int>().Should().Be(2);
            jp["limit"].Value<int>().Should().Be(3);
            jp["first"].Value<string>().Should().EndWith("&pageSize=3");
            jp["previous"].Value<string>().Should().EndWith("&pageSize=3");
            jp["next"].Value<string>().Should().EndWith("&pageSize=3");
            jp["last"].Value<string>().Should().EndWith("&pageSize=3");
        }




        /// <summary>
        /// 
        /// </summary>       
        [Fact]
        public async void FilterOptionsRouteShouldWorkAsExpected()
        {
            //Get options with manager (english user)
            ApiResponse a = await Util.GetAsync("Widget/FilterOptions", await Util.GetTokenAsync("manager", "l3tm3in"));
            Util.ValidateDataReturnResponseOk(a);
            Util.ValidateHTTPStatusCode(a, 200);
            a.ObjectResponse["data"]["key"].Value<string>().Should().Be("widget");
            ((JArray)a.ObjectResponse["data"]["flds"]).Count.Should().Be(9);
            a.ObjectResponse["data"]["flds"][3]["lt"].Value<string>().Should().Be("Price");

            a = await Util.GetAsync("Widget/FilterOptions", await Util.GetTokenAsync("es", "es"));
            Util.ValidateDataReturnResponseOk(a);
            Util.ValidateHTTPStatusCode(a, 200);
            a.ObjectResponse["data"]["flds"][3]["lt"].Value<string>().Should().Be("Importe");

            a = await Util.GetAsync("Widget/FilterOptions", await Util.GetTokenAsync("fr", "fr"));
            Util.ValidateDataReturnResponseOk(a);
            Util.ValidateHTTPStatusCode(a, 200);
            a.ObjectResponse["data"]["flds"][3]["lt"].Value<string>().Should().Be("Montant");

            a = await Util.GetAsync("Widget/FilterOptions", await Util.GetTokenAsync("de", "de"));
            Util.ValidateDataReturnResponseOk(a);
            Util.ValidateHTTPStatusCode(a, 200);
            a.ObjectResponse["data"]["flds"][3]["lt"].Value<string>().Should().Be("Betrag");

        }






        //==================================================

    }//eoc
}//eons
