using BarContracts.BindingModels;
using BarContracts.SearchModels;
using BarContracts.StoragesContracts;
using BarContracts.ViewModels;
using BarDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;

namespace BarDatabaseImplement.Implements
{
    public class OrderStorage : IOrderStorage
    {
        public List<OrderViewModel> GetFullList()
        {
            using var Context = new BarDatabase();

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

        public List<OrderViewModel> GetFilteredList(OrderSearchModel Model)
        {
            using var Context = new BarDatabase();

            if (Model.DateFrom.HasValue)
            {
                return Context.Orders
                    .Include(x => x.Cocktail)
                    .Include(x => x.Client)
                    .Include(x => x.Implementer)
                    .Where(x => (x.DateCreate >= Model.DateFrom && x.DateCreate <= Model.DateTo) && (!Model.ClientId.HasValue || x.ClientId == Model.ClientId))
                    .Select(x => x.GetViewModel)
                    .ToList();
            }

            return Context.Orders
                .Include(x => x.Cocktail)
                .Include(x => x.Client)
                .Include(x => x.Implementer)
                .Where(x => (Model.Id.HasValue && x.Id == Model.Id)
                    || (Model.ClientId.HasValue && x.ClientId == Model.ClientId)
                    || (Model.ImplementerId.HasValue && x.ImplementerId == Model.ImplementerId)
                    || (Model.Status.HasValue && x.Status == Model.Status))
                .Select(x => x.GetViewModel)
                .ToList();
        }

        public OrderViewModel? GetElement(OrderSearchModel Model)
        {
            if (!Model.Id.HasValue && !Model.ImplementerId.HasValue && !Model.Status.HasValue)
                return null;

            using var Context = new BarDatabase();

            return Context.Orders
                .Include(x => x.Cocktail)
                .Include(x => x.Client)
                .Include(x => x.Implementer)
                .FirstOrDefault(x => (Model.Id.HasValue && x.Id == Model.Id)
                    || (Model.ImplementerId.HasValue && Model.Status.HasValue && x.ImplementerId == Model.ImplementerId && x.Status == Model.Status))?
                .GetViewModel;
        }

        public OrderViewModel? Insert(OrderBindingModel Model)
        {
            if (Model == null)
                return null;

            var NewOrder = Order.Create(Model);
            if (NewOrder == null)
                return null;

            using var Context = new BarDatabase();

            Context.Orders.Add(NewOrder);
            Context.SaveChanges();

            return Context.Orders.Include(x => x.Cocktail).Include(x => x.Client).Include(x => x.Implementer).FirstOrDefault(x => x.Id == NewOrder.Id)?.GetViewModel;
        }

        public OrderViewModel? Update(OrderBindingModel Model)
        {
            using var Context = new BarDatabase();

            var Order = Context.Orders.FirstOrDefault(x => x.Id == Model.Id);
            if (Order == null)
                return null;

            Order.Update(Model);
            Context.SaveChanges();

            return Context.Orders.Include(x => x.Cocktail).Include(x => x.Client).Include(x => x.Implementer).FirstOrDefault(x => x.Id == Model.Id)?.GetViewModel;
        }

        public OrderViewModel? Delete(OrderBindingModel Model)
        {
            using var Context = new BarDatabase();
            var Order = Context.Orders.Include(x => x.Cocktail).Include(x => x.Client).Include(x => x.Implementer).FirstOrDefault(rec => rec.Id == Model.Id);

            if (Order == null)
                return null;

            Context.Orders.Remove(Order);
            Context.SaveChanges();

            return Order.GetViewModel;
        }
    }
}
