using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VeterinaryContracts.BindingModels;
using VeterinaryContracts.ViewModels;
using VeterinaryDataModels.Models;

namespace VeterinaryDatabaseImplement.Models
{
    public class Service : IServiceModel
	{
		public int Id { get; set; }
		[Required]
		public string ServiceName { get; set; } = string.Empty;
		[Required]
		public int DoctorId { get; private set; }
		public virtual Doctor? Doctor { get; private set; }

		[Required]
		public int VisitId { get; private set; }
		public virtual Visit? Visit { get; private set; }
	

		private Dictionary<int, IMedicationModel>? _serviceMedications = null;
		[NotMapped]
		public Dictionary<int, IMedicationModel> ServiceMedications
		{
			get
			{
				if (_serviceMedications == null)
				{
					_serviceMedications = Medications
					.ToDictionary(recPC => recPC.MedicationId, recPC =>
				   (recPC.Medication as IMedicationModel));
				}
				return _serviceMedications;
			}
		}
		[ForeignKey("ServiceId")]
		public virtual List<ServiceMedication> Medications { get; set; } = new();
		public static Service Create(VeterinaryDatabase context, ServiceBindingModel model)
		{
			return new Service()
			{
				Id = model.Id,
				ServiceName = model.ServiceName,
				DoctorId = model.DoctorId,
				VisitId = model.VisitId,
				Medications = model.ServiceMedications.Select(x => new ServiceMedication
				{
					Medication = context.Medications.First(y => y.Id == x.Key)
				}).ToList()
			};
		}
		public void Update(ServiceBindingModel model)
		{
			ServiceName = model.ServiceName;
		}
		public ServiceViewModel GetViewModel => new()
		{
			Id = Id,
			ServiceName = ServiceName,
			DoctorId = DoctorId,
			VisitId = VisitId,
			VisitName = Visit?.VisitName ?? string.Empty,
			ServiceMedications = ServiceMedications

		};

		public void UpdateMedications(VeterinaryDatabase context, ServiceBindingModel model)
		{
			var serviceMedications = context.ServiceMedications.Where(rec => rec.ServiceId == model.Id).ToList();
			if (serviceMedications != null && serviceMedications.Count > 0)
			{
				context.ServiceMedications.RemoveRange(serviceMedications.Where(rec => !model.ServiceMedications.ContainsKey(rec.MedicationId)));
				context.SaveChanges();
				foreach (var updateMedication in serviceMedications)
				{
					model.ServiceMedications.Remove(updateMedication.MedicationId);
				}
				context.SaveChanges();
			}
			var service = context.Services.First(x => x.Id == Id);
			foreach (var pc in model.ServiceMedications)
			{
				context.ServiceMedications.Add(new ServiceMedication
				{
					Service = service,
					Medication = context.Medications.First(x => x.Id == pc.Key)
				});
				context.SaveChanges();
			}
			_serviceMedications = null;
		}

	}
}
