using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using ReactiveUI;
using TravelAroundRussia.Models;

namespace TravelAroundRussia.ViewModels
{
    /// <summary>
    /// Модель Главная страница Туров, для просмотра всех туров
    /// </summary>
    public class MainTourPageViewModel : ReactiveObject
    {
        List<Tour> tourList = MainWindowViewModel.baseConnection.Tours.ToList();//лист со всемми турами
        List<String> typeList = new List<String>() { "Все типы" };//типы туров
        string typeListSelect = "Все типы";//выбранный тип тура
        string searchText = "";//строка поиска
        int sortListSelect = 0;//индекс выбранного значения
        bool actualFlag = false;//флаг отображения исключительно актуальных туров
        string srCount = "";//общая стоимость туров
        /// <summary>
        /// Свойство Список туров, при изменении вызывает метод для сортировки, фильтрации и поиска
        /// </summary>
        public List<Tour> TourList { get => tourList; set => this.RaiseAndSetIfChanged(ref tourList, value); }
        /// <summary>
        /// Свойство Списка типов, только вывод
        /// </summary>
        public List<String> TypeList
        {
            get
            {
                //добавляем все записи о турах из базы
                typeList.AddRange(MainWindowViewModel.baseConnection.Types.Select(tb => tb.Name).ToList());
                return typeList;
            }

        }
        /// <summary>
        /// Свойство отображения Типов туров, при изменении вызывает метод для сортировки, фильтрации и поиска и отрисовывает объект заново
        /// </summary>
        public string TypeListSelect { get => typeListSelect; set { this.RaiseAndSetIfChanged(ref typeListSelect, value); filter(); } }
        /// <summary>
        /// Свойство Строки поиска, при изменении вызывает метод для сортировки, фильтрации и поиска
        /// </summary>
        public string SearchText { get => searchText; set { searchText = value; filter(); } }
        /// <summary>
        /// Свойство выбранного элемента сортировки, при изменении вызывает метод для сортировки, фильтрации и поиска
        /// </summary>
        public int SortListSelect { get => sortListSelect; set { sortListSelect = value; filter(); } }
        /// <summary>
        /// Свойство отображения Актуальных записей, при изменении вызывает метод для сортировки, фильтрации и поиска
        /// </summary>
        public bool ActualFlag { get => actualFlag; set { actualFlag = value; filter(); } }
        /// <summary>
        /// Свойство Общая стоимость туров, которая заново отрисовывает объект в случае изменения
        /// </summary>
        public string SrCount 
        { get => "Общая стоимость билетов " + string.Format("{0:C2}",Math.Round(TourList.Sum(tb => tb.Price * tb.TicketCount),2));
          set => this.RaiseAndSetIfChanged(ref srCount, value); 
        }
        /// <summary>
        /// Метод для сортировки, фильтрации и поиска записей
        /// </summary>
        private void filter()
        {
            List<Tour> tourList = MainWindowViewModel.baseConnection.Tours.Include(tb => tb.CountryCodeNavigation).ToList();
            //поиск по имени и описанию
            //если строка не пустая, то ищем в наименовании туров введенную строку
            if (!string.IsNullOrWhiteSpace(SearchText))
                tourList = tourList.Where(tb => tb.Name.ToLower().Contains(SearchText.ToLower()) || tb._Descript.ToLower().Contains(SearchText.ToLower())).ToList();
            //фильтрация по актуальности
            //если фильтрация по актуальности включена, то отбираем только актуальные записи
            if (actualFlag)
                tourList = tourList.Where(tb => tb.IsActual == 1).ToList();
            //фильтрация по типу
            //если выбранный элемент - все типы или не выбран, то фильтрация не применяется
            if (typeListSelect != "Все типы" && typeListSelect != null)
            {
                //получаем экземпляр типа с выбранным наименованием
                Models.Type type = MainWindowViewModel.baseConnection.Types.FirstOrDefault(tb => tb.Name == typeListSelect);
                //получаем все записи, где тип тура совпадает с выбранным
                List<TypeOfTour> list = MainWindowViewModel.baseConnection.TypeOfTours.Where(tb => tb.TypeId == type.Id).ToList();
                //если количество записей больше 0
                if (list.Count > 0)
                {
                    int i = 0;//индекс записи в коллеции
                    while (i < tourList.Count)//пока не пройдем все листы
                    {
                        //принадлежность тура к выбранному типу
                        bool flag = list.FirstOrDefault(tb => tb.TourId == tourList[i].Id) != null;
                        if (!flag)//если не принадлежит удаляем этот эдемент
                            tourList.RemoveAt(i);
                        else//иначе переходим к следующему элементу
                            i++;
                    }
                }
                else//иначе удаляем все записи
                    tourList.Clear();
            }
            //сортировка по цене
            switch (SortListSelect)
            {
                case 0://сортировка по возрастанию цены
                    tourList = tourList.OrderBy(tb => tb.Price).ToList();
                    break;
                case 1://сортировка по убыванию цены
                    tourList = tourList.OrderByDescending(tb => tb.Price).ToList();
                    break;
            }

            TourList = tourList;//обновление цены
            //обновление информации об общей стоимости туров
            SrCount = "Общая стоимость билетов " + string.Format("{0:C2}", Math.Round(TourList.Sum(tb => tb.Price * tb.TicketCount), 2));
        }
    }
}