using Contracts.BusinessLogicsContracts;
using Contracts.ViewModels;
using Contracts.BindingModels;
using Contracts.StoragesContracts;
using Contracts.SearchModels;

namespace ImplementerApp
{
	public class ImplementerData
	{
		private readonly ILogger _logger;
		private readonly IImplementerLogic _implementerLogic;
		private readonly IDetailLogic _detailLogic;
		private readonly IProductionLogic _productionLogic;
		private readonly IProductLogic _productLogic;
		private readonly IMachineLogic _machineLogic;

		public ImplementerData(ILogger<ImplementerData> logger, IImplementerLogic implementerLogic, IDetailLogic detailLogic, IProductionLogic productionLogic, IProductLogic productLogic, IMachineLogic machineLogic)
		{
			_logger = logger;
			_implementerLogic = implementerLogic;
			_detailLogic = detailLogic;
			_productionLogic = productionLogic;
			_productLogic = productLogic;
			_machineLogic = machineLogic;
		}

		public ImplementerViewModel? Login(string login, string password)
		{
			return _implementerLogic.ReadElement(new()
			{
				Login = login,
				Password = password
			});
		}
		public bool Register(ImplementerBindingModel model)
		{
			return _implementerLogic.Create(model);
		}
		public bool UpdateUser(ImplementerBindingModel model)
		{
			return _implementerLogic.Update(model);
		}

		public List<DetailViewModel>? GetDetails(int userId)
		{
			return _detailLogic.ReadList(new DetailSearchModel() { UserId = userId });
		}
		public bool DeleteDetail(int detailId)
		{
			return _detailLogic.Delete(new() { Id = detailId });
		}
		public bool CreateDetail(DetailBindingModel model)
		{
			return _detailLogic.Create(model);
		}
		public bool UpdateDetail(DetailBindingModel model)
		{
			return _detailLogic.Update(model);
		}
		public DetailViewModel? GetDetail(int id)
		{
			return _detailLogic.ReadElement(new() { Id= id });
		}

		public List<ProductViewModel>? GetProducts(int userId)
		{
			return _productLogic.ReadList(new ProductSearchModel() { UserId = userId });
		}
		public ProductViewModel? GetProduct(int id)
		{
			return _productLogic.ReadElement(new() { Id = id });
		}
		public bool UpdateProduct(ProductBindingModel model)
		{ 
			return _productLogic.Update(model);
		}
		public bool DeleteProduct(int productId)
		{
			return _productLogic.Delete(new() { Id = productId });
		}
		public bool CreateProduct(ProductBindingModel model)
		{
			return _productLogic.Create(model);
		}

		public List<ProductionViewModel>? GetProductions(int userId)
		{
			return _productionLogic.ReadList(new() { UserId = userId });
		}
		public ProductionViewModel? GetProduction(int id)
		{
			return _productionLogic.ReadElement(new() { Id = id });
		}
		public bool CreateProduction(ProductionBindingModel model)
		{
			return _productionLogic.Create(model);
		}
		public bool UpdateProduction(ProductionBindingModel model)
		{
			return _productionLogic.Update(model);
		}
		public bool DeleteProduction(int productionId)
		{
			return _productionLogic.Delete(new() { Id = productionId});
		}	  
	
		public List<MachineViewModel>? GetMachines()
		{
			return _machineLogic.ReadList(null);
		}

		public List<DetailTimeReport> GetTimeReport(DateTime? startDate, DateTime? endDate, int UserId)
		{
			var details = _detailLogic.ReadList(new() { DateFrom = startDate, DateTo = endDate, UserId = UserId });
			if (details == null)
				return new();
			List<DetailTimeReport> detailTimeReports = new List<DetailTimeReport>();
			foreach (var detail in details)
			{
				var report = new DetailTimeReport();
				report.DetailName = detail.Name;
				var products = _productLogic.ReadList(new() { DetailId = detail.Id, UserId = UserId });
				if (products != null)
					report.Products = products.Select(p => p.Name).ToList();
				var productions = _productionLogic.ReadList(new() { DetailId = detail.Id, UserId = UserId });
				if (productions != null)
					report.Productions = productions.Select(p => p.Name).ToList();
				detailTimeReports.Add(report);
			}
			return detailTimeReports;
		}
	}
}
