using Contracts.BindingModels;
using Contracts.BusinessLogicContracts;
using Contracts.Converters;
using Contracts.Exceptions;
using Contracts.SearchModels;
using Contracts.StorageContracts;
using Contracts.ViewModels;
using DatabaseImplement.Implements;
using DatabaseImplement.Models;
using DataModels.Enums;
using DataModels.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BusinessLogic.BusinessLogic
{
	public class PurchaseLogic : IPurchaseLogic
	{
		private readonly IPurchaseStorage _purchaseStorage;
		private readonly ILogger _logger;

		public PurchaseLogic(IPurchaseStorage purchaseStorage, ILogger<PurchaseLogic> logger)
		{
			_purchaseStorage = purchaseStorage;
			_logger = logger;
		}

		public PurchaseViewModel Create(PurchaseBindingModel model)
		{
			ArgumentNullException.ThrowIfNull(model);

			var purchase = _purchaseStorage.Insert(model);
			if (purchase is null)
			{
				throw new Exception("Insert operation failed.");
			}

			return purchase;
		}

		public PurchaseViewModel Delete(PurchaseSearchModel model)
		{
			ArgumentNullException.ThrowIfNull(model);

			_logger.LogInformation("Delete purchase. Id: {0}", model.Id);
			var purchase = _purchaseStorage.Delete(model);
			if (purchase is null)
			{
				throw new Exception("Delete operation failed.");
			}

			return purchase;

        }

		public PurchaseViewModel ReadElement(PurchaseSearchModel model)
		{
			ArgumentNullException.ThrowIfNull(model);

			_logger.LogInformation("ReadElement. Id: {0}", model.Id);
			var purchase = _purchaseStorage.GetElement(model);
			if (purchase is null)
			{
				throw new ElementNotFoundException();
			}
			_logger.LogInformation("ReadElement find. Id: {0}", purchase.Id);

			return purchase;

        }

		public List<PurchaseViewModel> ReadElements(PurchaseSearchModel? model)
		{
			_logger.LogInformation("ReadList. Id: {Id}", model?.Id);
			var purchase_list = _purchaseStorage.GetFullList(model);
			if (purchase_list is null || purchase_list.Count() == 0)
			{
				_logger.LogWarning("ReadList return null list");
				return [];
			}
			_logger.LogInformation("ReadList. Count: {Count}", purchase_list.Count());

			return purchase_list;

        }

		public PurchaseViewModel Update(PurchaseBindingModel model)
		{
			ArgumentNullException.ThrowIfNull(model);

			var purchase = _purchaseStorage.Update(model);
			if (purchase is null)
			{
				throw new Exception("Update operation failed.");
			}
			return purchase;
		}
	}
}
