using DocumentFormat.OpenXml.Bibliography;
using DocumentFormat.OpenXml.Drawing.Charts;
using DocumentFormat.OpenXml.Presentation;
using DocumentFormat.OpenXml.Wordprocessing;
using System.Linq;
using TravelCompanyBusinessLogic.OfficePackage;
using TravelCompanyBusinessLogic.OfficePackage.HelperModels;
using TravelCompanyContracts.BindingModels;
using TravelCompanyContracts.BusinessLogicsContracts;
using TravelCompanyContracts.BusinessLogicsContracts.OperatorBusinessLogicsContracts;
using TravelCompanyContracts.SearchModels.OperatorSearchModels;
using TravelCompanyContracts.SearchModels.TouristSearchModels;
using TravelCompanyContracts.StoragesContracts.OperatorStoragesContracts;
using TravelCompanyContracts.StoragesContracts.TouristStoragesContracts;
using TravelCompanyContracts.ViewModels;
using TravelCompanyContracts.ViewModels.OperatorViewModels;
using TravelCompanyContracts.ViewModels.TouristViewModels;

namespace TravelCompanyBusinessLogic.BusinessLogics
{
    public class ReportLogic : IReportLogic
    {
        private readonly ITravelStorage travelStorage;
        private readonly IExcursionStorage excursionStorage;
        private readonly IGuideStorage guideStorage;
        private readonly AbstractSaveToPdf saveToPdf;
        private readonly AbstractSaveToWord saveToWord;
        private readonly AbstractSaveToExcel saveToExcel;
        public ReportLogic(ITravelStorage travelStorage, IExcursionStorage excursionStorage, 
            IGuideStorage guideStorage,
            AbstractSaveToPdf saveToPdf, AbstractSaveToWord saveToWord, AbstractSaveToExcel saveToExcel)
        {
            this.travelStorage = travelStorage;
            this.guideStorage = guideStorage;
            this.excursionStorage = excursionStorage;
            this.saveToPdf = saveToPdf;
            this.saveToWord = saveToWord;
            this.saveToExcel = saveToExcel;
        }
        public List<ReportTravelsPCView> GetTravelsPCView(ReportBindingModel model)
        {
            var list = new List<ReportTravelsPCView>();

            var travels = travelStorage.GetFilteredList(new TravelSearchModel
            {
                DateFrom =model.DateAfter,
                DateTo = model.DateBefore,
                TouristId = model.TouristId
            });

            foreach (var travel in travels)
            {
                var record = new ReportTravelsPCView
                {
                    DateCreate = travel.DateStart,
                    Excursions = new List<ExcursionViewModel>(),
                    Guids = new List<GuideViewModel>()
                };

                var excursions = travel.ExcursionTravels.Keys.ToList();
                foreach (var excrsionId in excursions)
                {
                    var excursion = excursionStorage.GetElement(new ExcursionSearchModel { Id = excrsionId });
                    record.Excursions.Add(excursion);
                    var excursionguide = excursion.GuideExcursions.Keys.ToList();
                    foreach (var guideId in excursionguide)
                    {
                        var guide = guideStorage.GetElement(new GuideSearchModel { Id = guideId });
                        record.Guids.Add(guide);
                    }
                }
                list.Add(record);
            }

            return list;
        }
        public List<ReportGuidesPCView> GetGuidesPCView(ReportBindingModel model)
        {
            var list = new List<ReportGuidesPCView>();

            var guides = guideStorage.GetFullList();

            var travels = travelStorage.GetFilteredList(new TravelSearchModel
            {
                TouristId= model.TouristId,
                DateFrom = model.DateAfter,
                DateTo = model.DateBefore,
            });

            foreach (var guide in guides)
            {
                var record = new ReportGuidesPCView
                {
                    GuideId = guide.Id,
                    FIO = guide.Surname+" "+guide.Name,
                    Travels = new List<TravelViewModel>()
                };

                foreach (var travel in travels)
                {
                    foreach(var excursion in travel.ExcursionTravels)
                    {
                        var findExcursion = excursionStorage.GetElement(new ExcursionSearchModel { Id = excursion.Key });
                        if (findExcursion.GuideExcursions.ContainsKey(guide.Id))
                        {
                            record.Travels.Add(travel);
                            break;
                        }
                    }
                }

                if (record.Travels.Count > 0) list.Add(record);
            }

            return list;
        }
        public List<ReportGuideView> GetGuidesByTravels(ReportBindingModel model)
        {
            var list = new List<ReportGuideView>();

            var traveles = travelStorage.GetFilteredList(new TravelSearchModel
            {
                TouristId = model.TouristId
            })

            foreach (var travel in traveles)
            {
                var record = new ReportGuideView
                {
                    Travel = travel,
                    Guides = new List<GuideViewModel>()
                };
                var travelExcursions = travel.ExcursionTravels.Keys.ToList();
                foreach (var excursionId in travelExcursions)
                {
                    var excursion = excursionStorage.GetElement(new ExcursionSearchModel { Id = excursionId });
                    var excursionGuides = excursion.GuideExcursions.Keys.ToList();

                    foreach (var guideId in excursionGuides)
                    {
                        if (record.Guides.Where(guide => guide.Id == guideId).ToList().Count == 0)
                        {
                            var guide = guideStorage.GetElement(new GuideSearchModel { Id = guideId });
                            record.Guides.Add(guide);
                        }
                    }
                }

                list.Add(record);
            }
            return list;
        }
        public void saveGuidesToPdfFile(ReportBindingModel model)
        {
            saveToPdf.CreateGuideDoc(new PdfInfo
            {
                Title = "Список гидов",
                DateAfter = model.DateAfter.Value,
                DateBefore = model.DateBefore.Value,
                FileName = (model.FileName != null) ? model.FileName : $"C:\\Users\\Public\\Documents\\{DateTime.Now.ToString("HH.mm.ss_dd.MM.yyyy")}.pdf",
                Guides = GetGuidesPCView(model)
            });
        }
        public void saveGuidesToExcel(ReportBindingModel model)
        {
            saveToExcel.CreateGuidesReport(new ExcelInfo()
            {
                Title = "Список гидов:",
                Guides = GetGuidesByTravels(model)
            });
        }
        public void saveGuidesToWord(ReportBindingModel model)
        {
            saveToWord.CreateGuidesDoc(new WordInfo()
            {
                Title = "Список гидов",
                Guides = GetGuidesByTravels(model)
            });
        }
    }
}
