using Avalonia.Controls.ApplicationLifetimes; using domain.Models; using domain.UseCase; using Presence.Desktop.Views; using ReactiveUI; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Reactive; using System.Reactive.Linq; using System.Windows.Input; using Avalonia; namespace Presence.Desktop.ViewModels { public class MainWindowViewModel : ViewModelBase { private readonly GroupUseCase _groupUseCase; private List groupPresentersDataSource = new List(); private ObservableCollection _groups; public ObservableCollection Groups => _groups; private GroupPresenter? _selectedGroupItem; public GroupPresenter? SelectedGroupItem { get => _selectedGroupItem; set => this.RaiseAndSetIfChanged(ref _selectedGroupItem, value); } public ObservableCollection Users { get => _users; } private ObservableCollection _users; // Список опций сортировки public List SortOptions { get; } = new List { "По фамилии", "По убыванию" }; private string _selectedSortOption; public string SelectedSortOption { get => _selectedSortOption; set => this.RaiseAndSetIfChanged(ref _selectedSortOption, value); } public bool CanDelete => SelectedUsers?.Count > 0; public bool CanEdit => SelectedUsers?.Count == 1; public ObservableCollection SelectedUsers { get; set; } = new ObservableCollection(); public ReactiveCommand OnDeleteUserClicks { get; } public ReactiveCommand EditUserCommand { get; } public ICommand RemoveAllStudentsCommand { get; } public ICommand AddStudentCommand { get; } public MainWindowViewModel(GroupUseCase groupUseCase) { _groupUseCase = groupUseCase; OnDeleteUserClicks = ReactiveCommand.Create(OnDeleteUserClick, this.WhenAnyValue(vm => vm.CanDelete)); EditUserCommand = ReactiveCommand.Create(OnEditUserClick, this.WhenAnyValue(vm => vm.CanEdit)); RefreshGroups(); _groups = new ObservableCollection(groupPresentersDataSource); _users = new ObservableCollection(); this.WhenAnyValue(vm => vm.SelectedGroupItem) .Subscribe(vm => SetUsers()); this.WhenAnyValue(vm => vm.SelectedSortOption) .Subscribe(_ => SortUsers()); RemoveAllStudentsCommand = ReactiveCommand.Create(RemoveAllStudents); AddStudentCommand = ReactiveCommand.Create(AddStudent); SelectedUsers.CollectionChanged += (s, e) => { this.RaisePropertyChanged(nameof(CanDelete)); this.RaisePropertyChanged(nameof(CanEdit)); }; } private void SetUsers() { if (SelectedGroupItem?.users == null) return; Users.Clear(); foreach (var item in SelectedGroupItem.users) { Users.Add(item); } SortUsers(); } private void SortUsers() { if (SelectedGroupItem?.users == null) return; var sortedUsers = SelectedGroupItem.users.ToList(); switch (SelectedSortOption) { case "По фамилии": sortedUsers = sortedUsers.OrderBy(u => u.Name).ToList(); break; case "По убыванию": sortedUsers = sortedUsers.OrderByDescending(u => u.Name).ToList(); break; } Users.Clear(); foreach (var item in sortedUsers) { Users.Add(item); } } private void RemoveAllStudents() { if (SelectedGroupItem == null) return; _groupUseCase.RemoveAllStudentsFromGroup(SelectedGroupItem.Id); SelectedGroupItem.users = new List(); SetUsers(); } private void AddStudent() { if (SelectedGroupItem == null) return; var newStudent = new UserPresenter { Name = "Новый студент", Guid = Guid.NewGuid(), Group = SelectedGroupItem }; _groupUseCase.AddStudentToGroup(SelectedGroupItem.Id, new User { Guid = newStudent.Guid, FIO = newStudent.Name }); var updatedUsers = SelectedGroupItem.users?.ToList() ?? new List(); updatedUsers.Add(newStudent); SelectedGroupItem.users = updatedUsers; SetUsers(); } public void OnDeleteUserClick() { if (SelectedUsers.Count == 0 || SelectedGroupItem?.users == null) return; foreach (var user in SelectedUsers.ToList()) { _groupUseCase.RemoveUserByGuid(user.Guid); var updatedUsers = SelectedGroupItem.users.Where(u => u.Guid != user.Guid).ToList(); SelectedGroupItem.users = new List(updatedUsers); } SetUsers(); SelectedUsers.Clear(); this.RaisePropertyChanged(nameof(CanDelete)); this.RaisePropertyChanged(nameof(CanEdit)); } public async void OnEditUserClick() { var user = SelectedUsers.FirstOrDefault(); if (user == null) return; var groups = _groupUseCase.GetAllGroups(); // Преобразуем группы из domain.Models.Group в GroupPresenter var groupPresenters = groups.Select(g => new GroupPresenter { Id = g.Id, Name = g.Name, users = g.Users?.Select(u => new UserPresenter { Name = u.FIO, Guid = u.Guid, Group = new GroupPresenter { Id = g.Id, Name = g.Name } }).ToList() }).ToList(); var editDialog = new EditUserDialog(user.Guid, user.Name, user.Group.Id, groupPresenters); var mainWindow = (Application.Current.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)?.MainWindow; if (mainWindow == null) return; var result = await editDialog.ShowDialog(mainWindow); if (result != (null, null)) { var newName = result.Item1; var newGroup = result.Item2; user.Name = newName; user.Group = newGroup; _groupUseCase.UpdateUser(user.Guid, user.Name, user.Group.Id); SetUsers(); SelectedUsers.Clear(); this.RaisePropertyChanged(nameof(CanEdit)); this.RaisePropertyChanged(nameof(CanDelete)); } RefreshGroups(); } private void RefreshGroups() { groupPresentersDataSource.Clear(); foreach (var item in _groupUseCase.GetAllGroups()) { GroupPresenter groupPresenter = new GroupPresenter { Id = item.Id, Name = item.Name, users = item.Users?.Select(user => new UserPresenter { Name = user.FIO, Guid = user.Guid, Group = new GroupPresenter { Id = item.Id, Name = item.Name } }).ToList() }; groupPresentersDataSource.Add(groupPresenter); } _groups = new ObservableCollection(groupPresentersDataSource); } } }