using DinerContracts.BindingModels;
using DinerContracts.SearchModels;
using DinerContracts.StoragesContracts;
using DinerContracts.ViewModels;
using DinerDataBaseImplement.Models;
using Microsoft.EntityFrameworkCore;

namespace DinerDataBaseImplement.Implements
{
	public class ImplementerStorage : IImplementerStorage
	{
		public List<ImplementerViewModel> GetFullList()
		{
			using var context = new DinerDatabase();

			return context.Implementers
				.Include(x => x.Orders)
				.Select(x => x.GetViewModel)
				.ToList();
		}
		public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
		{
			if (string.IsNullOrEmpty(model.ImplementerFIO))
			{
				return new();
			}

			using var context = new DinerDatabase();

			return context.Implementers
				.Include(x => x.Orders)
				.Where(x => x.ImplementerFIO.Contains(model.ImplementerFIO))
				.Select(x => x.GetViewModel)
				.ToList();
		}

		public ImplementerViewModel? GetElement(ImplementerSearchModel model)
		{
			using var context = new DinerDatabase();

			if (model.Id.HasValue)
			{
				return context.Implementers
				.Include(x => x.Orders)
				.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)
				?.GetViewModel;
			}
			else if (!string.IsNullOrEmpty(model.ImplementerFIO) && !string.IsNullOrEmpty(model.Password))
			{
				return context.Implementers
					.Include(x => x.Orders)
					.FirstOrDefault(x => (x.ImplementerFIO == model.ImplementerFIO && x.Password == model.Password))
					?.GetViewModel;
			}

			return new();
		}

		public ImplementerViewModel? Insert(ImplementerBindingModel model)
		{
			var newImplementer = Implementer.Create(model);

			if (newImplementer == null)
			{
				return null;
			}

			using var context = new DinerDatabase();

			context.Implementers.Add(newImplementer);
			context.SaveChanges();

			return context.Implementers
				.Include(x => x.Orders)
				.FirstOrDefault(x => x.Id == newImplementer.Id)
				?.GetViewModel;
		}

		public ImplementerViewModel? Update(ImplementerBindingModel model)
		{
			using var context = new DinerDatabase();
			var order = context.Implementers
				.Include(x => x.Orders)
				.FirstOrDefault(x => x.Id == model.Id);

			if (order == null)
			{
				return null;
			}

			order.Update(model);
			context.SaveChanges();

			return context.Implementers
				.Include(x => x.Orders)
				.FirstOrDefault(x => x.Id == model.Id)
				?.GetViewModel;
		}
		public ImplementerViewModel? Delete(ImplementerBindingModel model)
		{
			using var context = new DinerDatabase();

			var element = context.Implementers
				.FirstOrDefault(rec => rec.Id == model.Id);

			if (element != null)
			{
				var deletedElement = context.Implementers
					.Include(x => x.Orders)
					.FirstOrDefault(x => x.Id == model.Id)
					?.GetViewModel;

				context.Implementers.Remove(element);
				context.SaveChanges();

				return deletedElement;
			}

			return null;
		}
	}
}
