using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using OdataApplication.Models;
using WebApplication4.Data;
using WebApplication4.Models;
using OdataApplication.Models;
using Syncfusion.EJ2.Base;
using System.Collections;
using System.Security.Cryptography;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using WebApplication4.ViewModels;

namespace WebApplication4.Pages
{
    public class Index2Model : PageModel
    {
        private readonly IMapper mapper;
        private readonly NorthwndMdfContext _context;

        // Constructor for context injection
        public Index2Model(IMapper mapper, NorthwndMdfContext context)
        {
            this.mapper = mapper;
            _context = context;
        }

        public List<OrderVm> Orders { get; set; }

        public async Task OnGetAsync()
        {
            Orders = await _context.Orders.Include(o => o.ShipViaNavigation).ProjectTo<OrderVm>(mapper.ConfigurationProvider).ToListAsync();
        }

        // Action to handle URL data source requests
        public async Task<IActionResult> OnPostUrlDatasourceAsync([FromBody] DataManagerRequest dm)
        {
            try
            {
                IQueryable<Shipper> dataSource = _context.Shippers.Include(i => i.Orders);
                //IQueryable<Order> dataSource = _context.Orders
                //.Join(_context.Shippers,
                //      ord => ord.ShipVia,           // Join key from Orders
                //      shipper => shipper.ShipperId, // Join key from Shippers
                //      (ord, shipper) => new NewChangedData
                //      {
                //          Order = ord,
                //          CustomerId = string.Join(", ", shipper.Orders.Select(ci => ci.CustomerId))
                //      }).AsEnumerable() // as per microsoft suggestion use toList, IEnumerable to form rewrite query to resolve the issue. If we remove this, issue occurs.
                //      .Select(result => new Order
                //      {
                //          OrderId = result.Order.OrderId,
                //          CustomerId = result.CustomerId,
                //          Freight = result.Order.Freight,
                //          ShipCountry = result.Order.ShipCountry,
                //          ShipCity = result.Order.ShipCity,
                //          ShipRegion = result.Order.ShipRegion,
                //          ShipPostalCode = result.Order.ShipPostalCode,
                //          ShipAddress = result.Order.ShipAddress,
                //          OrderDate = result.Order.OrderDate,
                //          EmployeeId = result.Order.EmployeeId,
                //          ShippedDate = result.Order.ShippedDate,
                //          ShipVia = result.Order.ShipVia,
                //          RequiredDate = result.Order.RequiredDate,
                //          ShipName = result.Order.ShipName,
                //          ShipViaNavigation = result.Order.ShipViaNavigation
                //      }).AsQueryable(); ;
                var operations = new DataOperations();

                // Apply search, sorting, filtering, paging
                if (dm.Search != null && dm.Search.Count > 0)
                {
                    dataSource = operations.PerformSearching(dataSource, dm.Search); 
                }
                if (dm.Sorted != null && dm.Sorted.Count > 0)
                {
                    dataSource = operations.PerformSorting(dataSource, dm.Sorted);
                }
                if (dm.Where != null && dm.Where.Count > 0)//dm.Where != null && 
                {
                    dataSource = operations.PerformFiltering(dataSource, dm.Where, dm.Where[0].Operator);
                }

                int count = dataSource.Count();
                var aggregate = dm.Aggregates != null && dm.Aggregates.Count > 0 ? operations.PerformSelect(dataSource, dm.Aggregates.Select(s => s.Field).ToList()) : null;
                if (dm.Skip != 0)
                {
                    dataSource = operations.PerformSkip(dataSource, dm.Skip);
                }
                if (dm.Take != 0)
                {
                    dataSource = operations.PerformTake(dataSource, dm.Take);
                }

                var result = await dataSource.ProjectTo<ShipperVm>(mapper.ConfigurationProvider).ToListAsync();
                //return dm.RequiresCounts ? new JsonResult(new { result = dataSource, count, aggregate }) : new JsonResult(dataSource);
                return dm.RequiresCounts ? new JsonResult(new { result = result, count, aggregate }) : new JsonResult(dataSource);
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }

    }
    //public class NewChangedData
    //{
    //    public Order Order { get; set; }
    //    //public Shipper Shipper { get; set; }
    //    public string CustomerId { get; set; }
    //}
    //public class OrderController : Controller
    //{
    //    private readonly NorthwndMdfContext _context;

    //    // Dependency injection via constructor
    //    public OrderController(NorthwndMdfContext context)
    //    {
    //        _context = context;
    //    }

    //    public IActionResult Index()
    //    {
    //        return View();
    //    }

    //    [HttpPost]
    //    public IActionResult OnPostUrlDatasource([FromBody] DataManagerRequest dm)
    //    {
    //        // Build data source query
    //        IQueryable<Order> dataSource = _context.Orders.Include(o => o.ShipViaNavigation);
    //        //IQueryable<Order> dataSource = _context.Orders
    //        //.Join(_context.Shippers,
    //        //      ord => ord.ShipVia,           // Join key from Orders
    //        //      shipper => shipper.ShipperId, // Join key from Shippers
    //        //      (ord, shipper) => new NewChangedData
    //        //      {
    //        //          Order = ord,
    //        //          CustomerId = string.Join(", ", shipper.Orders.Select(ci => ci.CustomerId))
    //        //      }).AsEnumerable() // as per microsoft suggestion use toList, IEnumerable to form rewrite query to resolve the issue. If we remove this, issue occurs.
    //        //      .Select(result => new Order
    //        //      {
    //        //          OrderId = result.Order.OrderId,
    //        //          CustomerId = result.CustomerId,
    //        //          Freight = result.Order.Freight,
    //        //          ShipCountry = result.Order.ShipCountry,
    //        //          ShipCity = result.Order.ShipCity,
    //        //          ShipRegion = result.Order.ShipRegion,
    //        //          ShipPostalCode = result.Order.ShipPostalCode,
    //        //          ShipAddress = result.Order.ShipAddress,
    //        //          OrderDate = result.Order.OrderDate,
    //        //          EmployeeId = result.Order.EmployeeId,
    //        //          ShippedDate = result.Order.ShippedDate,
    //        //          ShipVia = result.Order.ShipVia,
    //        //          RequiredDate = result.Order.RequiredDate,
    //        //          ShipName = result.Order.ShipName,
    //        //          ShipViaNavigation = result.Order.ShipViaNavigation
    //        //      }).AsQueryable();

    //        var operations = new DataOperations();

    //        if (dm.Search != null && dm.Search.Count > 0)
    //        {
    //            dataSource = operations.PerformSearching(dataSource, dm.Search);
    //        }
    //        if (dm.Sorted != null && dm.Sorted.Count > 0)
    //        {
    //            dataSource = operations.PerformSorting(dataSource, dm.Sorted);
    //        }
    //        if (dm.Where != null && dm.Where.Count > 0)
    //        {
    //            dataSource = operations.PerformFiltering(dataSource, dm.Where, dm.Where[0].Operator);
    //        }

    //        int count = dataSource.Count();

    //        if (dm.Skip != 0)
    //        {
    //            dataSource = operations.PerformSkip(dataSource, dm.Skip);
    //        }
    //        if (dm.Take != 0)
    //        {
    //            dataSource = operations.PerformTake(dataSource, dm.Take);
    //        }

    //        return dm.RequiresCounts ? Json(new { result = dataSource, count = count }) : Json(dataSource);
    //    }
    //}
}
