using ElectronicsShopContracts.BindingModels;
using ElectronicsShopContracts.SearchModels;
using ElectronicsShopContracts.StorageContracts;
using ElectronicsShopContracts.ViewModels;
using ElectronicsShopDataBaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System.Xml.Linq;


namespace ElectronicsShopDataBaseImplement.Implements
{
    public class OrderStorage : IOrderStorage
    {
        public OrderViewModel? Insert(OrderBindingModel model)
        {
            using var context = new Database();
            var newComponent = Order.Create(context,model);
            if (newComponent == null)
            {
                return null;
            }
            context.Orders.Add(newComponent);
            context.SaveChanges();
            return newComponent.GetViewModel;
        }

		public OrderViewModel? Update(OrderBindingModel model) {
			using var context = new Database();
            using var transcation = context.Database.BeginTransaction();

			var order = context.Orders.FirstOrDefault(rec => rec.ID == model.ID);
			if (order == null) {
				return null;
			}
			order.UpdateProducts(context, model);
			transcation.Commit();
			return order.GetViewModel;
		}

        public OrderViewModel? DeleteProduct(OrderBindingModel model) {
			using var context = new Database();
			using var transcation = context.Database.BeginTransaction();

			var order = context.Orders.FirstOrDefault(rec => rec.ID == model.ID);
			if (order == null) {
				return null;
			}
			order.DeleteProducts(context, model);
			transcation.Commit();
			return order.GetViewModel;
		}

		public OrderViewModel? Delete(OrderBindingModel model)
        {
            using var context = new Database();
            var element = context.Orders.FirstOrDefault(rec => rec.ID == model.ID);
            if (element != null)
            {
                context.Orders.Remove(element);
                context.SaveChanges();
                return element.GetViewModel;
            }
            return null;
        }
        public OrderViewModel? GetElement(OrderSearchModel model)
        {
			using var context = new Database();
            if (model.ClientID.HasValue) {
                return context.Orders
                    .Include(x => x.Payments)
                    .Include(x => x.Products)
					.ThenInclude(x => x._product)
                    .OrderBy(x => x.ID)
				    .LastOrDefault(x => (model.ClientID.HasValue && x.ClientID == model.ClientID))?.GetViewModel;
			}
			if (model.ID.HasValue)
            {
				return context.Orders
			      .Include(x => x.Payments)
			      .Include(x => x.Products)
			      .ThenInclude(x => x._product)
			      .FirstOrDefault(x => (model.ID.HasValue && x.ID == model.ID))?.GetViewModel;
			}
            return null; 
        }

        public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
        {
			using var context = new Database();
			if (!model.ID.HasValue && model.DateFrom.HasValue && model.DateTo.HasValue)
            {
                return new();
            }
            else if (model.ClientID.HasValue) {
                return context.Orders
                    .Include (x => x.Products)
                    .Where(x => x.ClientID == model.ClientID)
                    .Select(x => x.GetViewModel)
                    .ToList();
            }
            return context.Orders
                .Include(x => x.Products)
                .ThenInclude(x => x._product)
                .Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo)
                .Select(x => x.GetViewModel)
                .ToList();
        }

        public List<OrderViewModel> GetFullList()
        {
            using var context = new Database();
			return context.Orders
                .Include(x => x.Products)
                .ThenInclude(x => x._product).ToList()
                .Select(x => x.GetViewModel).ToList();
        }
	}
}