using CanteenContracts.BindingModels;
using CanteenContracts.SearchModel;
using CanteenContracts.StoragesContracts;
using CanteenContracts.View;
using CanteenDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CanteenDatabaseImplement.Implements
{
    public class LunchStorage : ILunchStorage
    {
        public LunchViewModel? GetElement(LunchSearchModel model)
        {
            if (!model.Id.HasValue && !model.DateFrom.HasValue && !model.DateTo.HasValue)
            {
                return null;
            }

            using var context = new CanteenDatabase();

            return context.Lunches
                .Include(x => x.Products)
                .ThenInclude(x => x.Product)
                .FirstOrDefault(x => x.DateCreate >= model.DateFrom && x.DateImplement <= model.DateTo)?.GetViewModel;
        }

        public List<LunchViewModel> GetFilteredList(LunchSearchModel model)
        {
            if (!model.DateFrom.HasValue || !model.DateTo.HasValue)
            {
                return new();
            }

            using var context = new CanteenDatabase();

            return context.Lunches
                .Include(x => x.Products)
                .ThenInclude(x => x.Product)
                .Where(x => x.DateCreate >= model.DateFrom && x.DateImplement <= model.DateTo)
                .Select(x => x.GetViewModel).ToList();
        }

        public List<LunchViewModel> GetFullList()
        {
            using var context = new CanteenDatabase();
            return context.Lunches
                .Include(x => x.Products)
                .ThenInclude(x => x.Product)
                .Select(x => x.GetViewModel).ToList();
        }

        public LunchViewModel? Insert(LunchBindingModel model)
        {
            using var context = new CanteenDatabase();

            using var transaction = context.Database.BeginTransaction();
            {
                try
                {
                    var newLunch = Lunch.Create(context, model);
                    if (newLunch == null)
                    {
                        transaction.Rollback();
                        return null;
                    }

                    context.Lunches.Add(newLunch);

                    context.SaveChanges();
                    context.Database.CommitTransaction();

                    return newLunch.GetViewModel;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    return null;
                }
            }
        }

        public LunchViewModel? Update(LunchBindingModel model)
        {
            using var context = new CanteenDatabase();

            using var transaction = context.Database.BeginTransaction();
            {
                try
                {
                    var lunch = context.Lunches.FirstOrDefault(x => x.Id == model.Id);
                    if (lunch == null)
                    {
                        transaction.Rollback();
                        return null;
                    }

                    lunch.Update(model);

                    context.SaveChanges();
                    context.Database.CommitTransaction();

                    return lunch.GetViewModel;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    return null;
                }
            }
        }

        public LunchViewModel? Delete(LunchBindingModel model)
        {
            using var context = new CanteenDatabase();

            var element = context.Lunches.FirstOrDefault(rec => rec.Id == model.Id);
            if (element != null)
            {
                context.Lunches.Remove(element);
                context.SaveChanges();

                return element.GetViewModel;
            }

            return null;
        }
        public void AddOrder(LunchOrderBindingModel lunchOrder)
        {
            using var context = new CanteenDatabase();
            using var transaction = context.Database.BeginTransaction();
            try
            {
                if (context.LunchOrder.FirstOrDefault(rec => rec.LunchId == lunchOrder.LunchId && rec.OrderId == lunchOrder.OrderId) != null)
                {
                    var _lunchOrder = context.LunchOrder.FirstOrDefault(rec => rec.LunchId == lunchOrder.LunchId && rec.OrderId == lunchOrder.OrderId);
                    _lunchOrder.CountOrders = lunchOrder.OrderCount;
                }
                else
                {
                    context.LunchOrder.Add(new LunchOrder { LunchId = lunchOrder.LunchId, OrderId = lunchOrder.OrderId, CountOrders = lunchOrder.OrderCount });
                }
                context.SaveChanges();
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
    }
}
