using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VeterinaryContracts.StorageContracts;
using VeterinaryContracts.BindingModels;
using VeterinaryContracts.SearchModels;
using VeterinaryContracts.ViewModels;
using VeterinaryDatabaseImplement.Models;
using VeterinaryDatabaseImplement;
using Microsoft.EntityFrameworkCore;

namespace VeterinaryDatabaseImplement.Implements
{
	public class MedicationStorage : IMedicationStorage
	{
		public List<MedicationViewModel> GetFullList()
		{
			using var context = new VeterinaryDatabase();
			return context.Medications
			.Select(x => x.GetViewModel)
			.ToList();
		}
		public List<MedicationViewModel> GetFilteredList(MedicationSearchModel model)
		{
			
			using var context = new VeterinaryDatabase();
			return context.Medications.Where(x=>x.DoctorId == model.DoctorId)
			.Where(x => String.IsNullOrEmpty(model.MedicationName) || x.MedicationName.Contains(model.MedicationName))
		   .Select(x => x.GetViewModel)
		   .ToList();
		}
		public MedicationViewModel? GetElement(MedicationSearchModel model)
		{
			if (string.IsNullOrEmpty(model.MedicationName) && !model.Id.HasValue)
			{
				return null;
			}
			using var context = new VeterinaryDatabase();
			return context.Medications
			.FirstOrDefault(x =>
			(!string.IsNullOrEmpty(model.MedicationName) && x.MedicationName ==
			model.MedicationName) ||
			(model.Id.HasValue && x.Id == model.Id))
			?.GetViewModel;
		}
		public MedicationViewModel? Insert(MedicationBindingModel model)
		{
			var newMedication = Medication.Create(model);
			if (newMedication == null)
			{
				return null;
			}
			using var context = new VeterinaryDatabase();
			context.Medications.Add(newMedication);
			context.SaveChanges();
			return newMedication.GetViewModel;
		}
		public MedicationViewModel? Update(MedicationBindingModel model)
		{
			using var context = new VeterinaryDatabase();
			var medication = context.Medications.FirstOrDefault(x => x.Id ==model.Id);
			if (medication == null)
			{
				return null;
			}
			medication.Update(model);
			context.SaveChanges();
			return medication.GetViewModel;
		}
		public MedicationViewModel? Delete(MedicationBindingModel model)
		{
			using var context = new VeterinaryDatabase();
			var element = context.Medications.FirstOrDefault(rec => rec.Id == model.Id);
			if (element != null)
			{
				context.Medications.Remove(element);
				context.SaveChanges();
				return element.GetViewModel;
			}
			return null;
		}

		public List<ReportPurchaseMedicationViewModel> GetReportMedicationPurchasesList(ListPurchasesSearchModel model)
		{
			if (model.medicationsIds == null)
			{
				return new();
			}
			using var context = new VeterinaryDatabase();
			return context.Medications
				.Where(medication => model.medicationsIds == null || model.medicationsIds.Contains(medication.Id))
				.Select(medication => new ReportPurchaseMedicationViewModel()
				{
					MedicationName = medication.MedicationName,
					Purchases = context.Purchases.Include(purchase => purchase.Drug).ThenInclude(drug => drug.Medications)
				.Where(purchase => purchase.Drug != null && purchase.Drug.Medications.Any(m => m.MedicationId == medication.Id))
				.Select(purchase => purchase.GetViewModel).ToList()
				}).ToList();
		}

		public List<ReportDrugsVisitsViewModel> GetReportDrugsVisits(ReportDrugsVisitsSearchModel model)
		{
			using var context = new VeterinaryDatabase();

			return context.Medications
			  .Select(pet => new ReportDrugsVisitsViewModel()
			  {
				  MedicationName = pet.MedicationName,
				  Drugs = context.Drugs
				  .Where(drug => drug.DateCreate <= model.DateTo &&
					drug.DateCreate >= model.DateFrom && drug.Medications.Any(m => m.MedicationId == pet.Id))
				  .Select(drug => drug.GetViewModel)
				  .ToList(),
				  Visits = context.Services
				  .Include(service => service.Visit)
				  .Where(service => service.Visit != null && service.Visit.DateVisit <= model.DateTo &&
					service.Visit.DateVisit >= model.DateFrom && service.Medications.Any(m => m.MedicationId == pet.Id))
				  .Select(service => service.Visit.GetViewModel)
				  .ToList(),
			  })
			  .ToList();
		}



	}
}
