using BankContracts.BindingModels;
using BankContracts.BusinessLogicsContracts;
using BankContracts.StoragesContracts;
using BankContracts.ViewModels;
using BankContracts.SearchModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BankBusinessLogic.BusinessLogics
{
	public class ReportLogic : IReportLogic
	{
		private readonly ITransferStorage _transferStorage;
		private readonly IPaymentStorage _paymentStorage;
		private readonly ICurrencyPurchaseStorage _currencyPurchaseStorage;
		private readonly ICurrencyStorage _currencyStorage;

		public ReportLogic(ITransferStorage transferStorage, IPaymentStorage paymentStorage, ICurrencyPurchaseStorage currencyPurchaseStorage)
		{
			_transferStorage = transferStorage;
			_paymentStorage = paymentStorage;
			_currencyPurchaseStorage = currencyPurchaseStorage;
		}

		public List<ReportPaymentCurrencyPurchaseViewModel> GetPaymentPurchase(List<PaymentBindingModel> payments)
		{
			var list = new List<ReportPaymentCurrencyPurchaseViewModel>();
			var currencies = _currencyStorage.GetFullList();
			var currencyPurchases = _currencyPurchaseStorage.GetFullList();

			foreach(var payment in payments)
			{
				var record = new ReportPaymentCurrencyPurchaseViewModel
				{
					PaymentId = payment.Id,
					PaymentDate = payment.PaymentDate,
					Purchases = new List<(int, float)>()
				};
				var foundCurrenciesId = new List<int>();
				//находим валюты, привязанные к платежу
				foreach (var currency in currencies)
				{
                    if (payment.CurrencyPayments.ContainsKey(currency.Id)) foundCurrenciesId.Add(currency.Id);
                }
				//выбираем из всех закупок те, которые относятся к найденным валютам
                foreach (var currencyPurchase in currencyPurchases)
                {
					foreach(var currencyId in foundCurrenciesId)
					{
                        if (currencyPurchase.CurrencyId == currencyId)
                        {
                            record.Purchases.Add(new(currencyPurchase.Id, currencyPurchase.Amount));
							break;
                        }
                    }
                }
                list.Add(record);
			}

			return list;
		}

		public List<ReportTransferCurrencyPurchaseViewModel> GetTransferPurchase(ReportBindingModel model)
		{
			var transfers = _transferStorage.GetFilteredList(new TransferSearchModel { DateFrom = model.DateFrom, DateTo = model.DateTo });
			var currencies = _currencyStorage.GetFullList();
            var currencyPurchases = _currencyPurchaseStorage.GetFullList();
            var list = new List<ReportTransferCurrencyPurchaseViewModel>();

			foreach (var transfer in transfers)
			{
                var record = new ReportTransferCurrencyPurchaseViewModel
                {
                    TransferId = transfer.Id,
                    TransferDate = transfer.TransferDateTime,
                    Purchases = new List<(int, float)>()
                };
				var payment = _paymentStorage.GetElement(new PaymentSearchModel { Id = transfer.Id});
				if (payment == null)
				{
					throw new InvalidOperationException("Платеж не был найден!");
				}
				var foundCurrenciesId = new List<int>();
                //находим валюты, привязанные к платежу
                foreach (var currency in currencies)
                {
                    if (payment.CurrencyPayments.ContainsKey(currency.Id)) foundCurrenciesId.Add(currency.Id);
                }
                //выбираем из всех закупок те, которые относятся к найденным валютам
                foreach (var currencyPurchase in currencyPurchases)
                {
                    foreach (var currencyId in foundCurrenciesId)
                    {
                        if (currencyPurchase.CurrencyId == currencyId)
                        {
                            record.Purchases.Add(new(currencyPurchase.Id, currencyPurchase.Amount));
                            break;
                        }
                    }
                }
                list.Add(record);
            }
			
            return list;
        }

        public List<ReportCurrencyTransferViewModel> GetCurrencyTransfers(List<CurrencyBindingModel> currencies)
        {
            var list = new List<ReportCurrencyTransferViewModel>();
            var payments = _paymentStorage.GetFullList();
            var transfers = _transferStorage.GetFullList();
            foreach(var currency in currencies)
            {
                var record = new ReportCurrencyTransferViewModel
                {
                    CurrencyId = currency.Id,
                    CurrencyName = currency.Name,
                    Transfers = new List<(int TransferId, float Amount)>(),
                };
                var paymentsId = new List<int>();
                foreach(var payment in payments)
                {
                    if (payment.CurrencyPayments.ContainsKey(currency.Id)) paymentsId.Add(payment.Id);
                }
                foreach(var transfer in transfers)
                {
                    foreach(int paymentId in paymentsId)
                    {
                        if (paymentId == transfer.PaymentId)
                        {
                            record.Transfers.Add(new(transfer.Id, transfer.Amount));
                        }
                    }
                }
                list.Add(record);
            }
            return list;
        }
        public List<ReportCurrencyPurchasePaymentViewModel> GetPurchasePayment(ReportBindingModel model)
        {
            var purchases = _currencyPurchaseStorage.GetFilteredList(new CurrencyPurchaseSearchModel { DateFrom = model.DateFrom, DateTo = model.DateTo });
            var list = new List<ReportCurrencyPurchasePaymentViewModel>();
            var payments = _paymentStorage.GetFullList();
            foreach (var purchase in purchases)
            {
                var record = new ReportCurrencyPurchasePaymentViewModel
                {
                    CurrencyPurchaseId = purchase.Id,
                    PurchaseDate = purchase.PurchaseDate,
                    Payments = new List<(int PaymentId, string PaymentDate)>(),
                };
                var paymentsId = new List<int>();
                foreach (var payment in payments)
                {
                    if (payment.CurrencyPayments.ContainsKey(purchase.CurrencyId)) record.Payments.Add(new(payment.Id, payment.PaymentDate.ToString()));
                }
                list.Add(record);
            }
            return list;
        }

        public void SavePaymentPurchaseToExcel(List<PaymentBindingModel> payments)
		{
			var result = GetPaymentPurchase(payments);
			//создание файла будет реализовано в будующих версиях
			throw new NotImplementedException();
		}

		public void SavePaymentPurchaseToWord(List<PaymentBindingModel> payments)
		{
			var result = GetPaymentPurchase(payments);
            //создание файла будет реализовано в будующих версиях
            throw new NotImplementedException();
		}

		public void SaveTransferPurchaseToPDF(ReportBindingModel model)
		{
			var result = GetTransferPurchase(model);
            //создание файла будет реализовано в будующих версиях
            throw new NotImplementedException();
		}

        public void SaveCurrencyTransfersToExcel(List<CurrencyBindingModel> currencies)
        {
            var report = GetCurrencyTransfers(currencies);
            throw new NotImplementedException();
        }

        public void SaveCurrencyTransfersToWord(List<CurrencyBindingModel> currencies)
        {
            var report = GetCurrencyTransfers(currencies);
            throw new NotImplementedException();
        }
        public void SavePurchasePaymentToPDF(ReportBindingModel model)
        {
            var report = GetPurchasePayment(model);
            throw new NotImplementedException();
        }
    }
}
