using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VetClinicContracts.BindingModels;
using VetClinicContracts.BusinessLogicsContracts;
using VetClinicContracts.SearchModels;
using VetClinicContracts.StoragesContracts;
using VetClinicContracts.ViewModels;

namespace VetClinicBusinessLogic.BusinessLogics
{
	public class PharmacistLogic : IPharmacistLogic
	{
		private readonly ILogger _logger;
		private readonly IPharmacistStorage _pharmacistStorage;
		public PharmacistLogic(ILogger<PharmacistLogic> logger, IPharmacistStorage
	   pharmacistStorage)
		{
			_logger = logger;
			_pharmacistStorage = pharmacistStorage;
		}
		public List<PharmacistViewModel>? ReadList(PharmacistSearchModel? model)
		{
			_logger.LogInformation("ReadList. PharmacistFIO:{PharmacistFIO}. Id:{ Id}", model?.PharmacistFIO, model?.Id);
			var list = model == null ? _pharmacistStorage.GetFullList() :
	_pharmacistStorage.GetFilteredList(model);
			if (list == null)
			{
				_logger.LogWarning("ReadList return null list");
				return null;
			}
			_logger.LogInformation("ReadList. Count:{Count}", list.Count);
			return list;
		}
		public PharmacistViewModel? ReadElement(PharmacistSearchModel model)
		{
			if (model == null)
			{
				throw new ArgumentNullException(nameof(model));
			}
			_logger.LogInformation("ReadElement. PharmacistFIO:{PharmacistFIO}.Id:{ Id}", model.PharmacistFIO, model.Id);
			var element = _pharmacistStorage.GetElement(model);
			if (element == null)
			{
				_logger.LogWarning("ReadElement element not found");
				return null;
			}
			_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
			return element;
		}
		public bool Create(PharmacistBindingModel model)
		{
			CheckModel(model);
			if (_pharmacistStorage.Insert(model) == null)
			{
				_logger.LogWarning("Insert operation failed");
				return false;
			}
			return true;
		}
		public bool Update(PharmacistBindingModel model)
		{
			CheckModel(model);
			if (_pharmacistStorage.Update(model) == null)
			{
				_logger.LogWarning("Update operation failed");
				return false;
			}
			return true;
		}
		public bool Delete(PharmacistBindingModel model)
		{
			CheckModel(model, false);
			_logger.LogInformation("Delete. Id:{Id}", model.Id);
			if (_pharmacistStorage.Delete(model) == null)
			{
				_logger.LogWarning("Delete operation failed");
				return false;
			}
			return true;
		}
		private void CheckModel(PharmacistBindingModel model, bool withParams =
	   true)
		{
			if (model == null)
			{
				throw new ArgumentNullException(nameof(model));
			}
			if (!withParams)
			{
				return;
			}
			if (string.IsNullOrEmpty(model.PharmacistFIO))
			{
				throw new ArgumentNullException("Нет ФИО клиента",
			   nameof(model.PharmacistFIO));
			}
			if (string.IsNullOrEmpty(model.Email))
			{
				throw new ArgumentNullException("Нет Email клиента",
			   nameof(model.Email));
			}
			if (string.IsNullOrEmpty(model.Password))
			{
				throw new ArgumentNullException("Нет пароля клиента",
			   nameof(model.Password));
			}
			_logger.LogInformation("Pharmacist. PharmacistFIO:{PharmacistFIO}." +
				"Email:{ Email}. Password:{ Password}. Id: { Id} ", model.PharmacistFIO, model.Email, model.Password, model.Id);
			var element = _pharmacistStorage.GetElement(new PharmacistSearchModel
			{
				Email = model.Email,
			});
			if (element != null && element.Id != model.Id)
			{
				throw new InvalidOperationException("Клиент с таким логином уже есть");
			}
		}
	}
}
