using ComputerShopBusinessLogic.OfficePackage;
using ComputerShopBusinessLogic.OfficePackage.HelperModels;
using ComputerShopContracts.BindingModels;
using ComputerShopContracts.BusinessLogicContracts;
using ComputerShopContracts.StorageContracts;
using ComputerShopContracts.ViewModels;
using ComputerShopContracts.SearchModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComputerShopDataModels.Enums;

namespace ComputerShopBusinessLogic.BusinessLogics
{
    public class ReportLogic : IReportLogic
    {
        private readonly IComponentStorage _componentStorage;
        private readonly ISupplyStorage _supplyStorage;
        private readonly IAssemblyStorage _assemblyStorage;
        private readonly IEquipmentReceivingStorage _receivingStorage;
        private readonly IPurchaseStorage _purchaseStorage;
        private readonly AbstractSaveToExcel _saveToExcel;
        private readonly AbstractSaveToWord _saveToWord;
        private readonly AbstractSaveToPdf _saveToPdf;

        public ReportLogic(IComponentStorage componentStorage, IAssemblyStorage assemblyStorage, IEquipmentReceivingStorage receivingStorage, ISupplyStorage supplyStorage, IPurchaseStorage purchaseStorage, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord, AbstractSaveToPdf saveToPdf)
        {
            _componentStorage = componentStorage;
            _assemblyStorage = assemblyStorage;
            _receivingStorage = receivingStorage;
            _supplyStorage = supplyStorage;
            _purchaseStorage = purchaseStorage;
            _saveToExcel = saveToExcel;
            _saveToWord = saveToWord;
            _saveToPdf = saveToPdf;
        }

        public List<ReportComponentReceivingViewModel> GetComponentReceivings(List<int> ids)
        {
            var result = new List<ReportComponentReceivingViewModel>();

            var supplies1 = _supplyStorage.GetFullList();
            var recs = _receivingStorage.GetFullList();

            foreach (int id in ids)
            {
                var component = _componentStorage.GetElement(new ComponentSearchModel()
                {
                    Id = id,
                });
                var supplies = _supplyStorage.GetFilteredList(new()
                {
                    ComponentId = id
                });

                var receivings = new List<EquipmentReceivingViewModel>();

                foreach (var supply in supplies)
                {
                    if (supply.ReceivingId.HasValue)
                    {
                        var receiving = _receivingStorage.GetElement(new() { Id = supply.ReceivingId.Value });
                        if (receiving != null && !receivings.Contains(receiving))
                        {
                            receivings.Add(receiving);
                        }
                    }
                }


                var receivingnames = new List<string>();
                foreach (var receiving in receivings)
                {
                    receivingnames.Add($"Id: {receiving.Id}. Status: {Enum.GetName(typeof(EquipmentReceivingStatus), receiving.Status)}.");
                }
                if (receivingnames.Count > 0 && component != null)
                {
                    result.Add(new()
                    {
                        ComponentName = component.ComponentName,
                        Receivings = receivingnames
                    });
                }
            }


            return result;
        }

        public List<ReportPurchaseSupplyViewModel> GetPurchaseSupply(ReportBindingModel model)
        {
            var result = new List<ReportPurchaseSupplyViewModel>();
            var purchases = _purchaseStorage.GetFilteredList(new()
            {
                DateFrom = model.DateFrom,
                DateTo = model.DateTo
            });
            foreach(var purchase in purchases)
            {
                var supplies = _supplyStorage.GetFilteredList(new()
                {
                    ComponentId = purchase.ComponentId
                });
                foreach( var supply in supplies)
                {
                    result.Add(new()
                    {
                        Purchase = purchase,
                        Supply = supply
                    });
                }
            }
            return result;
        }

        public void SaveReceivingComponentsToWordFile(ReportBindingModel model)
        {
            if (model.Ids != null)
                _saveToWord.CreateDoc(new WordInfoProvider
                {
                    FileName = model.FileName,
                    Title = "Список получений по компонентам",
                    ComponentReceivings = GetComponentReceivings(model.Ids)
                });
        }

        public void SaveReceivingComponentsToXmlFile(ReportBindingModel model)
        {
            if (model.Ids != null)
                _saveToExcel.CreateReport(new ExcelInfoProvider
                {
                    FileName = model.FileName,
                    Title = "Список получений по компонентам",
                    ComponentReceivings = GetComponentReceivings(model.Ids)
                });
        }

        public void SavePurchaseSuppliesToPdfFile(ReportBindingModel model)
        {
            if (model.DateFrom == null)
            {
                throw new ArgumentException("Дата начала не задана");
            }

            if (model.DateTo == null)
            {
                throw new ArgumentException("Дата окончания не задана");
            }
            _saveToPdf.CreateDoc(new PdfInfoProvider
            {
                FileName = model.FileName,
                Title = "Связанные закупки и поставки",
                SupplyPurchases = GetPurchaseSupply(model),
                DateFrom = model.DateFrom,
                DateTo = model.DateTo
            });
        }

        public List<ReportPurchaseReceivingViewModel> GetPurchaseReceiving()
        {
            throw new NotImplementedException();
        }

        public void SaveOrdersToPdfFile(ReportBindingModel model)
        {
            throw new NotImplementedException();
        }

        public void SavePackagesToWordFile(ReportBindingModel model)
        {
            throw new NotImplementedException();
        }

        public void SaveProductComponentToExcelFile(ReportBindingModel model)
        {
            throw new NotImplementedException();
        }
    }
}