using Microsoft.EntityFrameworkCore;
using SoftwareInstallationContracts.BindingModels;
using SoftwareInstallationContracts.SearchModels;
using SoftwareInstallationContracts.StoragesContracts;
using SoftwareInstallationContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SoftwareInstallationDatabaseImplement.Implements
{
    public class OrderStorage : IOrderStorage
    {
        public OrderViewModel? Delete(OrderBindingModel model)
        {
            using var context = new SoftwareInstallationDatabase();

            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)
        {
            if (!model.Id.HasValue)
            {
                return null;
            }

            using var context = new SoftwareInstallationDatabase();

            return context.Orders.Include(x => x.Package)
                .Include(x => x.Client).Include(x => x.Implementer).FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
        }

        public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
        {
            using var context = new SoftwareInstallationDatabase();

            return context.Orders.Include(x => x.Package).Include(x => x.Implementer)
                .Include(x => x.Client).Where(x => (
                (!model.Id.HasValue || x.Id == model.Id) &&
                (!model.DateFrom.HasValue || x.DateCreate >= model.DateFrom) && (!model.DateTo.HasValue || x.DateCreate <= model.DateTo)
                &&
                (model.Statuses == null || model.Statuses != null && model.Statuses.Contains(x.Status)) &&
                        (!model.ImplementerId.HasValue || x.ImplementerId == model.ImplementerId)
                && (!model.ClientId.HasValue || x.ClientId == model.ClientId)))
                .Select(x => x.GetViewModel).ToList();
        }

        public List<OrderViewModel> GetFullList()
        {
            using var context = new SoftwareInstallationDatabase();

            return context.Orders.Include(x => x.Client).Include(x => x.Package).Include(x => x.Implementer).Select(x => x.GetViewModel).ToList();
        }

        public OrderViewModel? Insert(OrderBindingModel model)
        {
            var newOrder = Order.Create(model);

            if (newOrder == null)
            {
                return null;
            }

            using var context = new SoftwareInstallationDatabase();

            context.Orders.Add(newOrder);
            context.SaveChanges();

            return newOrder.GetViewModel;
        }

        public OrderViewModel? Update(OrderBindingModel model)
        {
            using var context = new SoftwareInstallationDatabase();

            var order = context.Orders.FirstOrDefault(x => x.Id == model.Id);

            if (order == null)
            {
                return null;
            }

            order.Update(model);
            context.SaveChanges();

            return order.GetViewModel;
        }
    }
}
