using MotorPlantContracts.BindingModels;
using MotorPlantContracts.SearchModels;
using MotorPlantContracts.StoragesContracts;
using MotorPlantContracts.ViewModels;
using MotorPlantDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;

namespace MotorPlantDatabaseImplement.Implements
{
    public class EngineStorage : IEngineStorage
    {
        public List<EngineViewModel> GetFullList()
        {
            using var context = new MotorPlantDataBase();
            return context.Engines
             .Include(x => x.Components)
            .ThenInclude(x => x.Component)
            .ToList()
            .Select(x => x.GetViewModel)
            .ToList();
        }
        public List<EngineViewModel> GetFilteredList(EngineSearchModel model)
        {
            if (string.IsNullOrEmpty(model.EngineName))
            {
                return new();
            }
            using var context = new MotorPlantDataBase();
            return context.Engines.Include(x => x.Components)
            .ThenInclude(x => x.Component)
            .Where(x => x.EngineName.Contains(model.EngineName))
            .ToList()
            .Select(x => x.GetViewModel)
            .ToList();
        }
        public EngineViewModel? GetElement(EngineSearchModel model)
        {
            if (string.IsNullOrEmpty(model.EngineName) &&
            !model.Id.HasValue)
            {
                return null;
            }
            using var context = new MotorPlantDataBase();
            return context.Engines
             .Include(x => x.Components)
             .ThenInclude(x => x.Component)
             .FirstOrDefault(x => (!string.IsNullOrEmpty(model.EngineName) &&
            x.EngineName == model.EngineName) ||
            (model.Id.HasValue && x.Id ==
            model.Id))
            ?.GetViewModel;
        }
        public EngineViewModel? Insert(EngineBindingModel model)
        {
            using var context = new MotorPlantDataBase();
            var newEngine = Engine.Create(context, model);
            if (newEngine == null)
            {
                return null;
            }
            context.Engines.Add(newEngine);
            context.SaveChanges();
            return newEngine.GetViewModel;
        }
        public EngineViewModel? Update(EngineBindingModel model)
        {
            using var context = new MotorPlantDataBase();
            using var transaction = context.Database.BeginTransaction();
            try
            {
                var Engine = context.Engines.FirstOrDefault(rec =>
                rec.Id == model.Id);
                if (Engine == null)
                {
                    return null;
                }
                Engine.Update(model);
                context.SaveChanges();
                Engine.UpdateComponents(context, model);
                transaction.Commit();
                return Engine.GetViewModel;
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
        public EngineViewModel? Delete(EngineBindingModel model)
        {
            using var context = new MotorPlantDataBase();
            var element = context.Engines
            .Include(x => x.Components)
            .FirstOrDefault(rec => rec.Id == model.Id);
            if (element != null)
            {
                context.Engines.Remove(element);
                context.SaveChanges();
                return element.GetViewModel;
            }
            return null;
        }
    }
}
