using SewingDressesBusinessLogic.OfficePackage;
using SewingDressesBusinessLogic.OfficePackage.HelperModels;
using SewingDressesContracts.BindingModels;
using SewingDressesContracts.BusinessLogicsContracts;
using SewingDressesContracts.SearchModels;
using SewingDressesContracts.StoragesContracts;
using SewingDressesContracts.ViewModels;

namespace SewingDressesBusinessLogic.BusinessLogic
{
    public class ReportLogic : IReportLogic
    {
        private readonly IComponentStorage _componentStorage;
        private readonly IDressStorage _dressStorage;
        private readonly IOrderStorage _orderStorage;
        private readonly AbstractSaveToExcel _saveToExcel;
        private readonly AbstractSaveToWord _saveToWord;
        private readonly AbstractSaveToPdf _saveToPdf;
        public ReportLogic(IComponentStorage componentStorage, IDressStorage dressStorage, IOrderStorage orderStorage, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord, AbstractSaveToPdf saveToPdf)
        {
            _componentStorage = componentStorage;
            _dressStorage = dressStorage;
            _orderStorage = orderStorage;
            _saveToExcel = saveToExcel;
            _saveToWord = saveToWord;
            _saveToPdf = saveToPdf;
        }
        public List<ReportDressComponentViewModel> GetDressComponent()
        {
            var components = _componentStorage.GetFullList();
            var dresses = _dressStorage.GetFullList();
            var list = new List<ReportDressComponentViewModel>();
            
            foreach ( var dress in dresses )
            {
                var record = new ReportDressComponentViewModel
                {
                    DressName = dress.DressName,
                    Components = new List<Tuple<string, int>>(),
                    TotalCount = 0
                };
                foreach (var component in components )
                {
                    if (dress.DressComponents.ContainsKey(component.Id))
                    {
                        record.Components.Add(new Tuple<string, int>(component.ComponentName, dress.DressComponents[component.Id].Item2));
                        record.TotalCount += dress.DressComponents[component.Id].Item2;
                    }
                }
                list.Add(record);
            }
            return list;
        }
        public List<ReportOrdersViewModel> GetOrders(ReportBindingModel model)
        {
            return _orderStorage.GetFilteredList(new OrderSearchModel
            {
                DateFrom = model.DateFrom,
                DateTo = model.DateTo
            }).Select(x => new ReportOrdersViewModel
            {
                Id = x.Id,
                DateCreate = x.DateCreate,
                DressName = x.DressName,
                Status = x.Status.ToString(),
                Sum = x.Sum
            }).ToList();
        }

        public void SaveComponentsToWordFile(ReportBindingModel model)
        {
            _saveToWord.CreateDoc(new WordInfo
            {
                FileName = model.FileName,
                Title = "Список платьев",
                Dresses = _dressStorage.GetFullList()
            });
        }

        public void SaveDressComponentToExcelFile(ReportBindingModel model)
        {
            _saveToExcel.CreateReport(new ExcelInfo
            {
                FileName = model.FileName,
                Title = "Список компонентов",
                DressComponents = GetDressComponent()
            }) ;
        }
        public void SaveOrdersToPdfFile(ReportBindingModel model)
        {
            _saveToPdf.CreateDoc(new PdfInfo
            {
                FileName = model.FileName,
                Title = "Список заказов",
                DateFrom = model.DateFrom!.Value,
                DateTo = model.DateTo!.Value,
                Orders = GetOrders(model)
            });
        }
    }
}
