using BlacksmithWorkshopBusinessLogic.OfficePackage;
using BlacksmithWorkshopBusinessLogic.OfficePackage.HelperModels;
using BlacksmithWorkshopContracts.BindingModels;
using BlacksmithWorkshopContracts.BusinessLogicsContracts;
using BlacksmithWorkshopContracts.SearchModels;
using BlacksmithWorkshopContracts.StoragesContracts;
using BlacksmithWorkshopContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BlacksmithWorkshopBusinessLogic.BusinessLogics
{
    public class ReportLogic : IReportLogic
    {
        private readonly IComponentStorage _componentStorage;
        private readonly IManufactureStorage _ManufactureStorage;
        private readonly IOrderStorage _orderStorage;
        private readonly IShopStorage _shopStorage;
        private readonly AbstractSaveToExcel _saveToExcel;
        private readonly AbstractSaveToWord _saveToWord;
        private readonly AbstractSaveToPdf _saveToPdf;
        public ReportLogic(IManufactureStorage ManufactureStorage, IComponentStorage componentStorage, 
                IOrderStorage orderStorage, AbstractSaveToExcel saveToExcel, IShopStorage shopStorage, 
                AbstractSaveToWord saveToWord, AbstractSaveToPdf saveToPdf)
        {
            _ManufactureStorage = ManufactureStorage;
            _componentStorage = componentStorage;
            _orderStorage = orderStorage;
            _shopStorage = shopStorage;
            _saveToExcel = saveToExcel;
            _saveToWord = saveToWord;
            _saveToPdf = saveToPdf;
        }
        /// <summary>
        /// Получение списка компонент с указанием, в каких изделиях используются
        /// </summary>
        /// <returns></returns>
        public List<ReportManufactureComponentViewModel> GetManufactureComponent()
        {
            var manufactures = _ManufactureStorage.GetFullList();
            var list = new List<ReportManufactureComponentViewModel>();
            foreach (var manufacture in manufactures)
            {
                var record = new ReportManufactureComponentViewModel
                {
                    ManufactureName = manufacture.ManufactureName,
                    Components = new List<Tuple<string, int>>(),
                    TotalCount = 0
                };
                foreach (var component in manufacture.ManufactureComponents)
                {
                    record.Components.Add(new Tuple<string, int>(
                        component.Value.Item1.ComponentName, component.Value.Item2));
                    record.TotalCount += component.Value.Item2;
                }
                list.Add(record);
            }
            return list;
        }
        /// <summary>
        /// Получение списка заказов за определенный период
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        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,
                ManufactureName = x.ManufactureName,
                Sum = x.Sum,
                OrderStatus = x.Status.ToString()
            })
           .ToList();
        }
        /// <summary>
        /// Сохранение компонент в файл-Word
        /// </summary>
        /// <param name="model"></param>
        public void SaveManufacturesToWordFile(ReportBindingModel model)
        {
            _saveToWord.CreateDoc(new WordInfo
            {
                FileName = model.FileName,
                Title = "Список кузнечных изделий",
                Manufactures = _ManufactureStorage.GetFullList()
            });
        }
        /// <summary>
        /// Сохранение компонент с указаеним продуктов в файл-Excel
        /// </summary>
        /// <param name="model"></param>
        public void SaveManufacturesComponentsToExcelFile(ReportBindingModel model)
        {
            _saveToExcel.CreateReport(new ExcelInfo
            {
                FileName = model.FileName,
                Title = "Список кузнечных изделий",
                ManufactureComponents = GetManufactureComponent()
            });
        }
        /// <summary>
        /// Сохранение заказов в файл-Pdf
        /// </summary>
        /// <param name="model"></param>
        public void SaveOrdersToPdfFile(ReportBindingModel model)
        {
            _saveToPdf.CreateDoc(new PdfInfo
            {
                FileName = model.FileName,
                Title = "Список заказов",
                DateFrom = model.DateFrom!.Value,
                DateTo = model.DateTo!.Value,
                Orders = GetOrders(model)
            });
        }
        public List<ReportShopsManufacturesViewModel> GetShopsManufactures()
        {
            var shops = _shopStorage.GetFullList();
            var list = new List<ReportShopsManufacturesViewModel>();
            foreach (var shop in shops)
            {
                var record = new ReportShopsManufacturesViewModel
                {
                    ShopName = shop.ShopName,
                    Manufactures = new List<Tuple<string, int>>(),
                    TotalCount = 0
                };
                foreach (var manufacture in shop.ShopManufactures)
                {
                    record.Manufactures.Add(new Tuple<string, int>(
                        manufacture.Value.Item1.ManufactureName, manufacture.Value.Item2));
                    record.TotalCount += manufacture.Value.Item2;
                }
                list.Add(record);
            }
            return list;
        }
        public List<ReportDatesOrdersViewModel> GetDatesOrders()
        {
            return _orderStorage.GetFullList().GroupBy(x => x.DateCreate.Date).Select(x => new ReportDatesOrdersViewModel
            {
                DateOfOrders = x.Key,
                Count = x.Count(),
                Sum = x.Sum(y => y.Sum)
            }).ToList();
        }
        public void SaveDatesOrdersToPdfFile(ReportBindingModel model)
        {
            _saveToPdf.CreateDatesOrdersReportDoc(new PdfInfo
            {
                FileName = model.FileName,
                Title = "Заказы по датам",
                DateOrders = GetDatesOrders()
            });
        }
        public void SaveShopsToWordFile(ReportBindingModel model)
        {
            var tmp = _shopStorage.GetFullList();
            _saveToWord.CreateShopsTableDoc(new WordInfo
            {
                FileName = model.FileName,
                Title = "Список магазинов",
                Shops = _shopStorage.GetFullList()
            });
        }
        public void SaveShopsManufacturesToExcelFile(ReportBindingModel model)
        {
            _saveToExcel.CreateShopReport(new ExcelInfo
            {
                FileName = model.FileName,
                Title = "Загруженность магазинов",
                ShopsManufactures = GetShopsManufactures()
            });
        }
    }
}
