using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VetClinicDataModels.Models;
using VetClinicContracts.BindingModels;
using VetClinicContracts.ViewModels;
using Microsoft.EntityFrameworkCore;

namespace VetClinicDataBaseImplement.Models
{
	public class Service : IServiceModel
	{
		public int Id { get; set; }
		[Required]
		public string ServiceName { get; set; } = string.Empty;
		[Required]
		public double Price { get; set; }
		[Required]
		public int PharmacistId { get; set; }
		public virtual Pharmacist Pharmacist { get; private set; }
		private Dictionary<int, (IMedicineModel, int)>? _serviceMedicines =
	   null;
		[NotMapped]
		public Dictionary<int, (IMedicineModel, int)> ServiceMedicines
		{
			get
			{
				if (_serviceMedicines == null)
				{
					_serviceMedicines = Medicines
					.ToDictionary(recPC => recPC.MedicineId, recPC =>
				   (recPC.Medicine as IMedicineModel, recPC.Count));
				}
				return _serviceMedicines;
			}
		}
		[ForeignKey("ServiceId")]
		public virtual List<ServiceMedicine> Medicines { get; set; } = new();
		[ForeignKey("ServiceId")]
		public virtual List<VisitService> Visits { get; set; } = new();
		[ForeignKey("ServiceId")]
		public virtual List<Guidance> Guidances { get; set; } = new();
		public static Service Create(VetClinicDatabase context,
	   ServiceBindingModel model)
		{
			return new Service()
			{
				Id = model.Id,
				ServiceName = model.ServiceName,
				Price = model.Price,
				Medicines = model.ServiceMedicines.Select(x => new
			   ServiceMedicine
				{
					Medicine = context.Medicines.First(y => y.Id == x.Key),
					Count = x.Value.Item2
				}).ToList()
			};
		}
		public void Update(ServiceBindingModel model)
		{
			ServiceName = model.ServiceName;
			Price = model.Price;
		}
		public ServiceViewModel GetViewModel => new()
		{
			Id = Id,
			ServiceName = ServiceName,
			Price = Price,
			ServiceMedicines = ServiceMedicines
		};
		public void UpdateMedicines(VetClinicDatabase context,
	   ServiceBindingModel model)
		{
			var serviceMedicines = context.ServiceMedicines.Where(rec =>
		   rec.ServiceId == model.Id).ToList();
			if (serviceMedicines != null && serviceMedicines.Count > 0)
			{
				context.ServiceMedicines.RemoveRange(serviceMedicines.Where(rec
=> !model.ServiceMedicines.ContainsKey(rec.MedicineId)));

				context.SaveChanges();
				foreach (var updateComponent in serviceMedicines)
				{
					updateComponent.Count =
				   model.ServiceMedicines[updateComponent.MedicineId].Item2;
					model.ServiceMedicines.Remove(updateComponent.MedicineId);
				}
				context.SaveChanges();
			}
			var service = context.Services.First(x => x.Id == Id);
			foreach (var pc in model.ServiceMedicines)
			{
				context.ServiceMedicines.Add(new ServiceMedicine
				{
					Service = service,
					Medicine = context.Medicines.Include(x => x.Animals).ThenInclude(x => x.Animal).First(x => x.Id == pc.Key),
					Count = pc.Value.Item2
				});
				context.SaveChanges();
			}
			_serviceMedicines = null;
		}
	}
}
