using Avalonia;
using Avalonia.Controls;
using Microsoft.EntityFrameworkCore;
using MsBox.Avalonia;
using MsBox.Avalonia.Base;
using MsBox.Avalonia.Enums;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Teachers.Models;

namespace Teachers.ViewModels
{
    internal class AddTeacherViewModel : ViewModelBase
    {
        //создаем нового учителя для дальнейшего добавления в бд
        Teacher? _newTeacher;
        public Teacher? NewTeacher { get => _newTeacher; set => this.RaiseAndSetIfChanged(ref _newTeacher, value); }
        string _buttonText;
        public string ButtonText { get => _buttonText; set => this.RaiseAndSetIfChanged(ref _buttonText, value); }

        //загружаем добавление учителя
        public AddTeacherViewModel()
        {
            _newTeacher = new Teacher()
            {
                //GenderNavigation = new Gender() //???что-то я совсем запуталась зачем написала это....
            };
            _newCourse = new Course();
            _buttonText = "Добавить учителя"; //разный текст на кнопке сохранения
        }
        //загружаем изменение существующего учителя
        public AddTeacherViewModel(int idTeacher)
        {
            _newTeacher = MainWindowViewModel.myConnection.Teachers
                .Include(x => x.GenderNavigation)
                .Include(x => x.TeacherCourses).ThenInclude(x => x.IdCourseNavigation)
                .Include(x => x.SubjectsTaughts).ThenInclude(x => x.IdSubjectNavigation).FirstOrDefault(x => x.Id == idTeacher); //считываем по ид данные о выбранном учителе

            _newCourse = new Course();
            CoursesTable = NewTeacher.TeacherCourses.ToList(); //подгружаем списочки для листбоксов
            SubjectsTable = NewTeacher.SubjectsTaughts.ToList();
            _buttonText = "Сохранить изменения";
        }

        #region Comboboxes
        //поля и свойства для работы со связью М:М
        List<TeacherCourse>? _coursesTable;
        List<SubjectsTaught>? _subjectsTable;
        public List<TeacherCourse>? CoursesTable { get => _coursesTable; set => this.RaiseAndSetIfChanged(ref _coursesTable, value); }
        public List<SubjectsTaught>? SubjectsTable { get => _subjectsTable; set => this.RaiseAndSetIfChanged(ref _subjectsTable, value); }

        //листы для отображения в комбобоксах (там где М:М в листы входят только те элементы, которых нету в листах-выбранных-значений
        List<Course> _coursesL = [new Course() { Id = 0, Name = "Выберите курс" }, .. MainWindowViewModel.myConnection.Courses.ToList()];
        List<Subject> _subjectL = [new Subject() { Id = 0, Name = "Выберите предмет" }, .. MainWindowViewModel.myConnection.Subjects.ToList()];
        public List<Gender> GendersL => MainWindowViewModel.myConnection.Genders.ToList();
        public List<Course> CoursesL => _coursesL
            .Except(_newTeacher.TeacherCourses.Select(x => x.IdCourseNavigation)).ToList();
        public List<Subject> SubjectsL => _subjectL
            .Except(_newTeacher.SubjectsTaughts.Select(x => x.IdSubjectNavigation)).ToList();

        //поле и свойство для добавления нового курса
        Course? _newCourse; 
        public Course? NewCourse { get => _newCourse; set => this.RaiseAndSetIfChanged(ref _newCourse, value); }


        //свойства добавления из комбобокса в листбокс и дальнейшего занесения в базу
        Course? selectedCourse;
        public Course? SelectedCourse
        {
            get
            {
                if (selectedCourse == null)
                {
                    return _coursesL[0];
                }
                else
                {
                    return selectedCourse;
                }
            }
            set
            {
                if (value != null)
                {
                    NewTeacher.TeacherCourses.Add 
                        (new TeacherCourse()
                        {
                            IdTeacherNavigation = NewTeacher, 
                            IdCourseNavigation = value
                        });
                    CoursesTable = NewTeacher.TeacherCourses.ToList(); 
                    this.RaisePropertyChanged(nameof(CoursesL));
                }
            }
        }
        Subject? selectedSubject;
        public Subject? SelectedSubject
        {
            get
            {
                if (selectedSubject == null)
                {
                    return _subjectL[0];
                }
                else
                {
                    return selectedSubject;
                }
            }
            set
            {
                if (value != null)
                {
                    NewTeacher.SubjectsTaughts.Add
                        (new SubjectsTaught()
                        {
                            IdTeacherNavigation = NewTeacher,
                            IdSubjectNavigation = value
                        });
                    SubjectsTable = NewTeacher.SubjectsTaughts.ToList();
                    this.RaisePropertyChanged(nameof(SubjectsL));
                }
            }
        }

        //методы для удаления выбранных курсов и предметов (М:М)
        public void DeleteCourse(TeacherCourse courseForDelete)
        {
            NewTeacher.TeacherCourses.Remove(courseForDelete);
            CoursesTable = NewTeacher.TeacherCourses.ToList(); //обновляем лист с выбранными значениями
            this.RaisePropertyChanged(nameof(CoursesL)); //обновляем лист с исходными значениями
        }
        public void DeleteSubject(SubjectsTaught subjectForDelete)
        {
            NewTeacher.SubjectsTaughts.Remove(subjectForDelete);
            SubjectsTable = NewTeacher.SubjectsTaughts.ToList(); //обновляем лист с выбранными значениями
            this.RaisePropertyChanged(nameof(SubjectsL)); //обновляем лист с исходными значениями
        }
        #endregion


        public void AddTeacher()
        {
            try
            {
                if (NewTeacher.Id == 0) //если текущего учителя не существует, т.е. в объекте newTeacher его Id равен 0, мы добавляем нового
                {
                    MainWindowViewModel.myConnection.Teachers.Add(NewTeacher);
                    MainWindowViewModel.myConnection.SaveChanges();
                    MessageBoxManager.GetMessageBoxStandard("Успех", "Учитель успешно добавлен!", MsBox.Avalonia.Enums.ButtonEnum.Ok).ShowAsync();
                }
                else
                {
                    MainWindowViewModel.myConnection.SaveChanges();
                    MessageBoxManager.GetMessageBoxStandard("Успех", "Учитель успешно изменен!", MsBox.Avalonia.Enums.ButtonEnum.Ok).ShowAsync();
                }              
                
                MainWindowViewModel.Instance.Us = new TeachersView();
            }
            catch (Exception ex)
            {
                MessageBoxManager.GetMessageBoxStandard("Внимание", ex.Message + "\n" + ex.StackTrace, MsBox.Avalonia.Enums.ButtonEnum.Ok).ShowAsync();
            }
        }

        //для кнопки назад
        public void ToTeachersView()
        {
            MainWindowViewModel.Instance.Us = new TeachersView();
        }

        //для открытия окна добавления курса
        public async Task ShowAddCourse()
        {
            var window = new Window();
            window.Width = 400;
            window.Height = 225;
            window.Content = new AddCourseView();
            window.Title = "Добавление курса";
            window.Show();
        }
    }
}
