using Demo.Domain.Models; using Demo.Domain.UseCase; using DynamicData; using DynamicData.Binding; using Presence.Desktop.Models; using ReactiveUI; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Reactive; using System.Reactive.Linq; using Avalonia.Controls; using Presence.Desktop.Views; using Avalonia.Input; namespace Presence.Desktop.ViewModels { public class GroupViewModel : ViewModelBase, IRoutableViewModel { private readonly IGroupUseCase _groupUseCase; private readonly IUserUseCase _userUseCase; private ObservableCollection _groups; public ObservableCollection Groups => _groups; private ObservableCollection _users; public ObservableCollection Users => _users; private GroupPresenter? _selectedGroupItem; public GroupPresenter? SelectedGroupItem { get => _selectedGroupItem; set => this.RaiseAndSetIfChanged(ref _selectedGroupItem, value); } private ObservableCollection _secondComboBoxItems = new ObservableCollection { "no sort", "name sort", "name sort rev" }; public ObservableCollection SecondComboBoxItems => _secondComboBoxItems; private string? _selectedSecondItem; public string? SelectedSecondItem { get => _selectedSecondItem; set => this.RaiseAndSetIfChanged(ref _selectedSecondItem, value); } private UserPresenter? _selectedUser; public UserPresenter? SelectedUser { get => _selectedUser; set => this.RaiseAndSetIfChanged(ref _selectedUser, value); } private ObservableCollection _selectedUsers = new ObservableCollection(); public ObservableCollection SelectedUsers { get => _selectedUsers; set => this.RaiseAndSetIfChanged(ref _selectedUsers, value); } private bool _isMultipleUsersSelected; public bool IsMultipleUsersSelected { get => _isMultipleUsersSelected; set => this.RaiseAndSetIfChanged(ref _isMultipleUsersSelected, value); } private string? _newFIO; public string? NewFIO { get => _newFIO; set => this.RaiseAndSetIfChanged(ref _newFIO, value); } public UserPresenter? SelectedUserForUpdate { get => SelectedUsers?.FirstOrDefault(); set => this.RaiseAndSetIfChanged(ref _selectedUser, value); } public ReactiveCommand ButtonRemoveUsersByGroup { get; } public ReactiveCommand ImportStudentsCommand { get; } public ReactiveCommand, Unit> RemoveSelectedUsersCommand { get; } public ReactiveCommand UpdateUserFIOCommand { get; } public GroupViewModel(IGroupUseCase groupUseCase, IUserUseCase userUseCase) { _groupUseCase = groupUseCase; _userUseCase = userUseCase; _groups = new ObservableCollection(); _users = new ObservableCollection(); RefreshGroups(); this.WhenAnyValue(vm => vm.SelectedGroupItem) .Subscribe(_ => { RefreshGroups(); SetUsers(); }); this.WhenAnyValue(vm => vm.SelectedSecondItem) .Subscribe(_ => SetUsers()); this.WhenAnyValue(vm => vm.SelectedUsers.Count) .Subscribe(count => IsMultipleUsersSelected = count > 1); SelectedSecondItem = _secondComboBoxItems.First(); ButtonRemoveUsersByGroup = ReactiveCommand.Create(() => RemoveUsersByGroup()); ImportStudentsCommand = ReactiveCommand.CreateFromTask(async () => await ImportStudents()); RemoveSelectedUsersCommand = ReactiveCommand.Create>(DeleteUsers); UpdateUserFIOCommand = ReactiveCommand.Create(UpdateUserFIO); } private void SetUsers() { if (SelectedGroupItem == null) return; Users.Clear(); var group = _groups.FirstOrDefault(it => it.Id == SelectedGroupItem.Id); if (group?.users == null) return; var sortedUsers = SelectedSecondItem switch { "name sort" => group.users.OrderBy(user => user.Name), "name sort rev" => group.users.OrderByDescending(user => user.Name), _ => group.users }; foreach (var user in sortedUsers) { Users.Add(user); } } private void RefreshGroups() { _groups.Clear(); foreach (var group in _groupUseCase.GetAllGroupsWithUsers()) { var groupPresenter = new GroupPresenter { Id = group.ID, Name = group.Name, users = group.Users?.Select(user => new UserPresenter { Name = user.FIO, Guid = user.Guid, Group = new GroupPresenter { Id = group.ID, Name = group.Name } }).ToList() }; _groups.Add(groupPresenter); } } private void RemoveUsersByGroup() { if (SelectedGroupItem == null) return; _groupUseCase.RemoveUsersByGroup(SelectedGroupItem.Id); RefreshGroups(); SetUsers(); } private async System.Threading.Tasks.Task ImportStudents() { if (SelectedGroupItem == null || SelectedGroupItem.Id == null) return; var openFileDialog = new OpenFileDialog { Filters = new List { new FileDialogFilter { Name = "CSV Files", Extensions = { "csv" } } }, AllowMultiple = false }; var result = await openFileDialog.ShowAsync(new Window()); if (result?.Length > 0) { var filePath = result[0]; var lines = File.ReadAllLines(filePath); foreach (var line in lines.Skip(1)) { var columns = line.Split(','); if (columns.Length < 1) continue; var fio = columns[0]; var newUser = new User { FIO = fio, Group = new Group { Name = SelectedGroupItem.Name, ID = SelectedGroupItem.Id } }; var isCreated = _userUseCase.CreateUser(newUser); if (isCreated) { RefreshGroups(); SetUsers(); } } } } private void DeleteUsers(IEnumerable users) { if (users == null) return; var usersToDelete = new List(users); foreach (var user in usersToDelete) { var isDeleted = _userUseCase.RemoveUserByGuid(user.Guid); if (isDeleted) { Users.Remove(user); } } } private void DeleteUser(UserPresenter user) { if (user == null) return; var isDeleted = _userUseCase.RemoveUserByGuid(user.Guid); if (isDeleted) { Users.Remove(user); } } private void UpdateUserFIO(UserPresenter user) { Console.WriteLine("start"); if (user == null || string.IsNullOrWhiteSpace(NewFIO)) return; user.Name = NewFIO; var updatedUser = new User { Guid = user.Guid, FIO = NewFIO, Group = new Group { ID = SelectedGroupItem.Id, Name = SelectedGroupItem.Name } }; var isUpdated = _userUseCase.UpdateUser(updatedUser); Console.WriteLine("end"); if (isUpdated != null) { NewFIO = string.Empty; // SelectedUsers.Clear(); // Очистить выбранных пользователей // SelectedUser = null; // Обнулить выбранного пользователя // SelectedUserForUpdate = null; RefreshGroups(); SetUsers(); } } public string? UrlPathSegment { get; } public IScreen HostScreen { get; } } }