using ComputerHardwareStoreContracts.BindingModels;
using ComputerHardwareStoreContracts.SearchModels;
using ComputerHardwareStoreContracts.StorageContracts;
using ComputerHardwareStoreContracts.ViewModels;
using ComputerHardwareStoreDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;

namespace ComputerHardwareStoreDatabaseImplement.Implements
{
    public class BuildStorage : IBuildStorage
    {
        public List<BuildViewModel> GetFullList()
        {
            using var context = new ComputerHardwareStoreDBContext();
            return context.Builds
                .Include(b => b.Comments)
                .Include(b => b.Components)
                .ThenInclude(b => b.Component)
                .Select(b => b.GetViewModel)
                .ToList();
        }

        public List<BuildViewModel> GetFilteredList(BuildSearchModel model)
        {
            if (string.IsNullOrEmpty(model.Name))
            {
                return new();
            }
            using var context = new ComputerHardwareStoreDBContext();
            return context.Builds
                .Where(b => b.Name.Contains(model.Name))
                .Include(b => b.Comments)
                .Include(b => b.Components)
                .ThenInclude(b => b.Component)
                .Select(b => b.GetViewModel)
                .ToList();
        }

        public BuildViewModel? GetElement(BuildSearchModel model)
        {
            if (string.IsNullOrEmpty(model.Name) && !model.Id.HasValue)
            {
                return null;
            }
            using var context = new ComputerHardwareStoreDBContext();
            return context.Builds
                .Include(b => b.Comments)
                .Include(b => b.Components)
                .ThenInclude(b => b.Component)
                .FirstOrDefault(b =>
                (!string.IsNullOrEmpty(model.Name) && b.Name == model.Name) ||
                (model.Id.HasValue && b.Id == model.Id))?
                .GetViewModel;
        }        

        public BuildViewModel? Insert(BuildBindingModel model)
        {
            using var context = new ComputerHardwareStoreDBContext();
            var newBuild = Build.Create(context, model);
            if (newBuild == null)
            {
                return null;
            }
            context.Builds.Add(newBuild);
            context.SaveChanges();
            return context.Builds
                .Include(b => b.Comments)
                .Include(b => b.Components)
                .ThenInclude(b => b.Component)
                .FirstOrDefault(p => p.Id == newBuild.Id)?
                .GetViewModel;
        }

        public BuildViewModel? Update(BuildBindingModel model)
        {
            using var context = new ComputerHardwareStoreDBContext();
            var build = context.Builds
                .Include(b => b.Comments)
                .Include(b => b.Components)
                .ThenInclude(b => b.Component)
                .FirstOrDefault(p => p.Id == model.Id);
            if (build == null)
            {
                return null;
            }
            context.Update(model);
            context.SaveChanges();
            return build.GetViewModel;
        }
        public BuildViewModel? Delete(BuildBindingModel model)
        {
            using var context = new ComputerHardwareStoreDBContext();
            var build = context.Builds
                .Include(b => b.Comments)
                .Include(b => b.Components)
                .ThenInclude(b => b.Component)
                .FirstOrDefault(p => p.Id == model.Id);
            if (build == null)
            {
                return null;
            }
            context.Builds.Remove(build);
            context.SaveChanges();
            return build.GetViewModel;
        }
    }
}