using Contracts.BindingModels;
using Contracts.SearchModels;
using Contracts.StorageContracts;
using Contracts.ViewModels;
using DatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DatabaseImplement.Implements
{
	public class PurchaseStorage : IPurchaseStorage
	{
		public PurchaseViewModel? Delete(PurchaseSearchModel model)
		{
            using var context = new Database();
            var element = context.Purchases.FirstOrDefault(rec => rec.Id == model.Id);
            if (element != null)
            {
                context.Purchases.Remove(element);
                context.SaveChanges();
                return element.GetViewModel;
            }
            return null;
        }

		public PurchaseViewModel? GetElement(PurchaseSearchModel model)
		{
            if (!model.Id.HasValue)
            {
                return null;
            }
            using var context = new Database();
            return context.Purchases
            .Include(x => x.Products)
            .ThenInclude(x => x.Product)
            .FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
        }

		public List<PurchaseViewModel> GetFullList(PurchaseSearchModel? model)
		{
            using var context = new Database();
            return context.Purchases
            .Include(x => x.Products)
            .ThenInclude(x => x.Product)
            .ToList()
            .Select(x => x.GetViewModel)
            .ToList();
        }
        public List<PurchaseViewModel> GetFilteredList(PurchaseSearchModel? model)
        {
            using var context = new Database();
            return context.Purchases
            .Include(x => x.Products)
            .ThenInclude(x => x.Product)
            .ToList()
            .Select(x => x.GetViewModel)
            .ToList();
        }

        public PurchaseViewModel? Insert(PurchaseBindingModel model)
		{
            using var context = new Database();
            var purchase = Purchase.Create(context, model);
            if (purchase == null)
                return null;
            context.Purchases.Add(purchase);
            context.SaveChanges();
            return purchase.GetViewModel;
        }

		public PurchaseViewModel? Update(PurchaseBindingModel model)
		{
            using var context = new Database();
            using var transaction = context.Database.BeginTransaction();
            try
            {
                var purchase = context.Purchases.FirstOrDefault(rec =>
                rec.Id == model.Id);
                if (purchase == null)
                {
                    return null;
                }
                purchase.Update(model);
                context.SaveChanges();
                purchase.UpdateProducts(context, model);
                transaction.Commit();
                return purchase.GetViewModel;
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
	}
}