using BankContracts.BindingModels;
using BankContracts.SearchModels;
using BankContracts.StoragesContracts;
using BankContracts.ViewModels;
using BankDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;

namespace BankDatabaseImplement.Implements
{
    public class CostStorage : ICostStorage
    {
        private void CheckSearchModel(CostSearchModel model)
        {
            if (model == null)
                throw new ArgumentNullException("Передаваемая модель для поиска равна нулю", nameof(model));
            if (!model.Id.HasValue && !model.EmployeeId.HasValue)
                throw new ArgumentException("Все передаваемые поля поисковой модели оказались пусты или равны null");
        }
        public CostViewModel? Delete(CostBindingModel model)
        {
            using var context = new BankDB();
            var element = context.Costs.FirstOrDefault(x => x.Id == model.Id);
            if (element != null)
            {
                context.Costs.Remove(element);
                context.SaveChanges();
                return element.GetViewModel;
            }
            return null;
        }

        public CostViewModel? GetElement(CostSearchModel model)
        {
            CheckSearchModel(model);
            using var context = new BankDB();
            if (!model.Id.HasValue)
            {
                return null;
            }
            return context.Costs
                .Include(cost => cost.Employee)
                .Include(cost => cost.Purchases).ThenInclude(costByPurchase => costByPurchase.Purchase)
                .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)?.GetViewModel;
        }

        public List<CostViewModel> GetFilteredList(CostSearchModel model)
        {
            CheckSearchModel(model);
            using var context = new BankDB();
            return context.Costs
                .Include(cost => cost.Employee)
                .Include(cost => cost.Purchases).ThenInclude(costByPurchase => costByPurchase.Purchase)
                .Where(x => x.EmployeeId == model.EmployeeId || x.Id == model.Id)
                .Select(x => x.GetViewModel)
                .ToList();
        }

        public List<CostViewModel> GetFullList()
        {
            using var context = new BankDB();
            return context.Costs
                .Include(cost => cost.Employee)
                .Include(cost => cost.Purchases).ThenInclude(costByPurchase => costByPurchase.Purchase)
                .Select(x => x.GetViewModel)
                .ToList();
        }

        public CostViewModel? Insert(CostBindingModel model)
        {
            var newCost = Cost.Create(model);
            if (newCost == null)
            {
                return null;
            }
            using var context = new BankDB();

            context.Costs.Add(newCost);
            context.SaveChanges();
            return newCost.GetViewModel;
        }
        public CostViewModel? Update(CostBindingModel model)
        {
            using var context = new BankDB();
            var cost = context.Costs.FirstOrDefault(x => x.Id == model.Id);
            if (cost == null)
            {
                return null;
            }
            cost.Update(model);
            context.SaveChanges();
            cost.UpdatePurchases(context, model);
            context.SaveChanges();
            return cost.GetViewModel;
        }
    }
}
