using VetClinicContracts.BindingModels;
using VetClinicContracts.SearchModels;
using VetClinicContracts.StoragesContracts;
using VetClinicContracts.ViewModels;
using VetClinicDataBaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using VetClinicDataBaseImplement;

namespace VetClinicDataBaseImplement.Implements
{
	public class AdminStorage : IAdminStorage
	{
		public AdminViewModel? Delete(AdminBindingModel model)
		{
			using var context = new VetClinicDatabase();
			var element = context.Admins
				.FirstOrDefault(rec => rec.Id == model.Id);

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

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

				return deletedElement;
			}
			return null;
		}

		public AdminViewModel? GetElement(AdminSearchModel model)
		{
			using var context = new VetClinicDatabase();
			if (model.Id.HasValue)
			{
				return context.Admins
				.Include(x => x.Visits)
				.Include(x => x.Animals)
				.FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id)
				?.GetViewModel;
			}
			else if (!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password))
			{
				return context.Admins
					.Include(x => x.Visits)
					.Include(x => x.Animals)
					.FirstOrDefault(x => (x.Email == model.Email && x.Password == model.Password))
					?.GetViewModel;
			}
			return new();
		}

		public List<AdminViewModel> GetFilteredList(AdminSearchModel model)
		{
			if (string.IsNullOrEmpty(model.AdminFIO))
			{
				return new();
			}
			using var context = new VetClinicDatabase();

			return context.Admins
				.Include(x => x.Visits)
				.Include(x => x.Animals)
				.Where(x => x.AdminFIO.Contains(model.AdminFIO))
				.Select(x => x.GetViewModel)
				.ToList();
		}

		public List<AdminViewModel> GetFullList()
		{
			using var context = new VetClinicDatabase();

			return context.Admins
				.Include(x => x.Visits)
				.Include(x => x.Animals)
				.Select(x => x.GetViewModel)
				.ToList();
		}

		public AdminViewModel? Insert(AdminBindingModel model)
		{
			var newAdmin = Admin.Create(model);
			if (newAdmin == null)
			{
				return null;
			}
			using var context = new VetClinicDatabase();
			context.Admins.Add(newAdmin);
			context.SaveChanges();

			return context.Admins
				.Include(x => x.Visits)
				.Include(x => x.Animals)
				.FirstOrDefault(x => x.Id == newAdmin.Id)
				?.GetViewModel;
		}

		public AdminViewModel? Update(AdminBindingModel model)
		{
			using var context = new VetClinicDatabase();
			var order = context.Admins
				.Include(x => x.Visits)
				.Include(x => x.Animals)
				.FirstOrDefault(x => x.Id == model.Id);
			if (order == null)
			{
				return null;
			}
			order.Update(model);
			context.SaveChanges();

			return context.Admins
				.Include(x => x.Visits)
				.Include(x => x.Animals)
				.FirstOrDefault(x => x.Id == model.Id)
				?.GetViewModel;
		}
	}
}
