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

namespace ShipyardBusinessLogic.BusinessLogics
{
    public class ReportLogic: IReportLogic
    {
        private readonly IDetailStorage _detailStorage;

        private readonly IShipStorage _shipStorage;

        private readonly IOrderStorage _orderStorage;
        private readonly IShopStorage _shopStorage;

        private readonly AbstractSaveToExcel _saveToExcel;

        private readonly AbstractSaveToWord _saveToWord;

        private readonly AbstractSaveToPdf _saveToPdf;

        public ReportLogic(IShipStorage shipStorage, IDetailStorage detailStorage, IOrderStorage orderStorage,IShopStorage shopStorage,
            AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord, AbstractSaveToPdf saveToPdf)
        {
            _shipStorage = shipStorage;
            _detailStorage = detailStorage;
            _orderStorage = orderStorage;
            _shopStorage = shopStorage;

            _saveToExcel = saveToExcel;
            _saveToWord = saveToWord;
            _saveToPdf = saveToPdf;
        }
        public List<ReportShipDetailViewModel> GetShipDetail()
        {

            var ships = _shipStorage.GetFullList();

            var list = new List<ReportShipDetailViewModel>();

            foreach (var ship in ships)
            {
                var record = new ReportShipDetailViewModel
                {
                    ShipName = ship.ShipName,
                    Details = new List<(string, int)>(),
                    TotalCount = 0
                };
                foreach (var shipDetail in ship.ShipDetails)
                {

                    record.Details.Add(new(shipDetail.Value.Item1.DetailName, shipDetail.Value.Item2));
                    record.TotalCount += shipDetail.Value.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,
                        ShipName = x.ShipName,
                        OrderStatus=x.Status.ToString(),
                        Sum = x.Sum
                    })
                    .ToList();
        }

        public void SaveComponentsToWordFile(ReportBindingModel model)
        {
            _saveToWord.CreateDoc(new WordInfo
            {
                FileName = model.FileName,
                Title = "Список кораблей",
                Ships = _shipStorage.GetFullList()
            });
        }

        public void SaveProductComponentToExcelFile(ReportBindingModel model)
        {
            _saveToExcel.CreateReport(new ExcelInfo
            {
                FileName = model.FileName,
                Title = "Список деталей",
                ShipDetails = GetShipDetail()
            });
        }

        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<ReportShopShipViewModel> GetShopShips()
        {
            var ships = _shipStorage.GetFullList();

            var shops = _shopStorage.GetFullList();

            var list = new List<ReportShopShipViewModel>();

            foreach (var shop in shops)
            {
                var record = new ReportShopShipViewModel
                {
                    ShopName = shop.ShopName,
                    Ships = new List<(string, int)>(),
                    TotalCount = 0
                };
                foreach (var ship in ships)
                {
                        record.Ships.Add(new(ship.ShipName, shop.ShopShips[ship.Id].Item2));
                        record.TotalCount += shop.ShopShips[ship.Id].Item2;
                }

                list.Add(record);
            }

            return list;
        }

        public void SaveShopShipToExcelFile(ReportBindingModel model)
        {
            _saveToExcel.CreateShopReport(new ExcelInfo
            {
                FileName = model.FileName,
                Title = "Заполненность магазинов",
                ShopShips = GetShopShips()
            });
        }

        public List<ReportOrdersGroupedByDateViewModel> GetGroupedByDateOrders()
        {
            return _orderStorage.GetFullList().GroupBy(x=>x.DateCreate.Date)
                     .Select(x => new ReportOrdersGroupedByDateViewModel
                     {
                         Date=x.Key,
                         Count=x.Count(),
                         Sum = x.Sum(y=>y.Sum)
                     })
                     .ToList();
        }

        public void SaveGroupedByDateOrders(ReportBindingModel model)
        {
            _saveToPdf.CreateDocWithGroupedOrders(new PdfInfo
            {
                FileName = model.FileName,
                Title = "Заказы по дате",
                GroupedOrders = GetGroupedByDateOrders()
            });
        }

        public void SaveShopsToWordFile(ReportBindingModel model)
        {
            _saveToWord.CreateShopsTable(new WordInfo
            {
                FileName = model.FileName,
                Title = "Список магазинов",
                Shops = _shopStorage.GetFullList()
            });
        }
    }
}
