using ComputersShopBusinessLogic.OfficePackage;
using ComputersShopBusinessLogic.OfficePackage.HelperModels;
using ComputersShopContracts.BindingModels;
using ComputersShopContracts.BusinessLogicContracts;
using ComputersShopContracts.SearchModels;
using ComputersShopContracts.StoragesContracts;
using ComputersShopContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ComputersShopBusinessLogic.BusinessLogics
{
	public class ReportLogic : IReportLogic
	{
		private readonly IComponentStorage _componentStorage;
        private readonly IComputerStorage _ComputerStorage;
        private readonly IOrderStorage _orderStorage;
        private readonly AbstractSaveToExcel _saveToExcel;
        private readonly AbstractSaveToWord _saveToWord;
        private readonly AbstractSaveToPdf _saveToPdf;

        public ReportLogic(IComputerStorage ComputerStorage, IComponentStorage componentStorage, IOrderStorage orderStorage, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord, AbstractSaveToPdf saveToPdf)
        {
            _ComputerStorage = ComputerStorage;
            _componentStorage = componentStorage;
            _orderStorage = orderStorage;
            _saveToExcel = saveToExcel;
            _saveToWord = saveToWord;
            _saveToPdf = saveToPdf;
        }
        
        public List<ReportComputerComponentViewModel> GetComputerComponents()
        {
            var components = _componentStorage.GetFullList();
            var Computers = _ComputerStorage.GetFullList();
            var list = new List<ReportComputerComponentViewModel>();
            foreach (var Computer in Computers)
            {
                var record = new ReportComputerComponentViewModel
                {
                    ComputerName = Computer.ComputerName,
                    Components = new List<(string Component, int Count)>(),
                    TotalCount = 0
                };
                foreach (var component in components)
                {
                    if (Computer.ComputerComponents.ContainsKey(component.Id))
                    {
                        record.Components.Add(new(component.ComponentName, Computer.ComputerComponents[component.Id].Item2));
                        record.TotalCount += Computer.ComputerComponents[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,
                ComputerName = x.ComputerName,
                Sum = x.Sum,
                Status = x.Status.ToString(),
            })
           .ToList();
        }

        public void SaveComputersToWordFile(ReportBindingModel model)
        {
            _saveToWord.CreateDoc(new WordInfo
            {
                FileName = model.FileName,
                Title = "Список компьютеров",
                Computers = _ComputerStorage.GetFullList()
            });
        }
        
        public void SaveComputerComponentToExcelFile(ReportBindingModel model)
        {
            _saveToExcel.CreateReport(new ExcelInfo
            {
                FileName = model.FileName,
                Title = "Список компьютеров",
                ComputerComponents = GetComputerComponents()
            });
        }
        
        public void SaveOrdersToPdfFile(ReportBindingModel model)
        {
            _saveToPdf.CreateDoc(new PdfInfo
            {
                FileName = model.FileName,
                Title = "Список заказов",
                DateFrom = DateTime.SpecifyKind(model.DateFrom!.Value, DateTimeKind.Utc),
                DateTo = DateTime.SpecifyKind(model.DateTo!.Value, DateTimeKind.Utc),
                Orders = GetOrders(model)
            });
        }
	}
}
