using Microsoft.EntityFrameworkCore;
using MsBox.Avalonia;
using MsBox.Avalonia.Dto;
using MsBox.Avalonia.Enums;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Teachers.Models;
using Teachers.ViewModels;

namespace Teachers.ViewModels
{
    internal class TeachersViewModel : ViewModelBase
    {
        List<Teacher> _teachersList;
        List<Subject> _subjectList = [new Subject() { Id = 0, Name = "Предмет не выбран" }, .. MainWindowViewModel.myConnection.Subjects.ToList()];
        string _searchStr;
        bool isCheckedGender1 = false;
        bool isCheckedGender2 = false;
        bool removeSort = true;
        bool isCheckedPhone = false;
        bool sortUp = true;
        bool sortDown = false;
        bool removeSortHours = true;
        bool sortUpHours = false;
        bool sortDownHours = false;
        int selectedSort = 0;
        bool isEnabledSort = false;
        Subject selectedSubject = null;

        public List<Teacher> TeachersList { get => _teachersList; set => this.RaiseAndSetIfChanged(ref _teachersList, value); }
        public List<Subject> SubjectList { get => _subjectList; }
        public string SearchStr { get { return _searchStr; }  set { _searchStr = value; DoFilter(); } }
        public bool IsCheckedGender1 { get => isCheckedGender1; set { this.RaiseAndSetIfChanged(ref isCheckedGender1, value); DoFilter(); } }
        public bool IsCheckedGender2 { get => isCheckedGender2; set { this.RaiseAndSetIfChanged(ref isCheckedGender2, value); DoFilter(); } }
        public bool RemoveSort { get => removeSort; set { this.RaiseAndSetIfChanged(ref removeSort, value); DoFilter(); } }
        public bool RemoveSortHours { get => removeSortHours; set { this.RaiseAndSetIfChanged(ref removeSortHours, value); DoFilter(); } }
        public bool IsCheckedPhone { get => isCheckedPhone; set { this.RaiseAndSetIfChanged(ref isCheckedPhone, value); DoFilter(); } }
        public bool SortUp { get => sortUp; set { this.RaiseAndSetIfChanged(ref sortUp, value); DoFilter(); } }
        public bool SortDown { get => sortDown; set { this.RaiseAndSetIfChanged(ref sortDown, value); DoFilter(); } }
        public bool SortUpHours { get => sortUpHours; set { this.RaiseAndSetIfChanged(ref sortUpHours, value); DoFilter(); } }
        public bool SortDownHours { get => sortDownHours; set { this.RaiseAndSetIfChanged(ref sortDownHours, value); DoFilter(); } }
        public int SelectedSort { get => selectedSort; set { selectedSort = value; DoFilter(); } }
        public bool IsEnabledSort { get => isEnabledSort; set { this.RaiseAndSetIfChanged(ref isEnabledSort, value); } }
        public Subject SelectedSubject { get { if (selectedSubject == null) return _subjectList[0]; else return selectedSubject; } set { selectedSubject = value; DoFilter(); } }

        public TeachersViewModel()
        {
            TeachersList = MainWindowViewModel.myConnection.Teachers
            .Include(x => x.GenderNavigation)
            .Include(x => x.SubjectsTaughts).ThenInclude(x => x.IdSubjectNavigation)
            .Include(x => x.TeacherCourses).ThenInclude(x => x.IdCourseNavigation)
            .ToList();
        }

        void DoFilter()
        {
            TeachersList = MainWindowViewModel.myConnection.Teachers
            .Include(x => x.GenderNavigation)
            .Include(x => x.SubjectsTaughts).ThenInclude(x => x.IdSubjectNavigation)
            .Include(x => x.TeacherCourses).ThenInclude(x => x.IdCourseNavigation)
            .ToList();

            if (!string.IsNullOrWhiteSpace(_searchStr))
            {
                TeachersList = TeachersList.Where(x => x.FIO.ToLower().Contains(_searchStr.ToLower())).ToList();
            }

            if (IsCheckedGender1 || IsCheckedGender2)
            {
                removeSort = false;
                if (isCheckedGender1)
                {
                    TeachersList = TeachersList.Where(x => x.Gender == 1).ToList();
                }
                else
                {
                    TeachersList = TeachersList.Where(x => x.Gender == 2).ToList();
                }
            }

            if (RemoveSort)
            {
                isCheckedGender1 = false;
                isCheckedGender2 = false;
                TeachersList = TeachersList.Where(x => x.Gender == 2 || x.Gender == 1).ToList();
            }

            if (IsCheckedPhone)
            {
                TeachersList = TeachersList.Where(x => x.Phone != null && x.Phone != "").ToList();
            }

            if (selectedSubject != null && selectedSubject.Id != 0)
            {
                TeachersList = TeachersList.Where(x => x.SubjectsTaughts.Any(y => y.IdSubjectNavigation == selectedSubject)).ToList();
            }

            if (sortUpHours || sortDownHours)
            {
                removeSortHours = false;
                if (sortUpHours)
                {
                    TeachersList = TeachersList.OrderBy(x => x.CoursesHoursInt).ToList();
                }
                else
                {
                    TeachersList = TeachersList.OrderByDescending(x => x.CoursesHoursInt).ToList();
                }
            }

            if (RemoveSortHours)
            {
                sortUpHours = false;
                sortDownHours = false;
            }

            switch (selectedSort)
            {
                case 0:
                    IsEnabledSort = false;
                    break;
                case 1:
                    IsEnabledSort = true;
                    if (sortUp)
                    {
                        TeachersList = TeachersList.OrderBy(x => x.Experience).ToList();
                    }
                    else
                    {
                        TeachersList = TeachersList.OrderByDescending(x => x.Experience).ToList();
                    }
                    break;
                case 2:
                    IsEnabledSort = true;
                    if (sortUp)
                    {
                        TeachersList = TeachersList.OrderBy(x => x.Surname).ToList();
                    }
                    else
                    {
                        TeachersList = TeachersList.OrderByDescending(x => x.Surname).ToList();
                    }
                    break;
            }
        }

        public async void DeleteTeacher(int id)
        {
            Teacher teacherForDelete = MainWindowViewModel.myConnection.Teachers.First(x => x.Id == id);
            ButtonResult result = await MessageBoxManager.GetMessageBoxStandard("Внимание", "Вы уверены, что хотите удалить " + teacherForDelete.FIO + "?", MsBox.Avalonia.Enums.ButtonEnum.YesNo).ShowAsync();
            switch (result)
            {
                case ButtonResult.Yes:
                    {
                        MainWindowViewModel.myConnection.Teachers.Remove(teacherForDelete);
                        MainWindowViewModel.myConnection.SaveChanges();
                        MessageBoxManager.GetMessageBoxStandard("Успех", "Учитель " + teacherForDelete.FIO + " успешно удален!", MsBox.Avalonia.Enums.ButtonEnum.Ok).ShowAsync();
                        MainWindowViewModel.Instance.Us = new TeachersView();
                        break;
                    }
                case ButtonResult.No:
                    {
                        break;
                    }
            }
        }

        public void ToAdd()
        {
            MainWindowViewModel.Instance.Us = new AddTeacherView();
        }
        public void ToUpdate(int idTeacher)
        {
            MainWindowViewModel.Instance.Us = new AddTeacherView(idTeacher);
        }
    }
}
