using Avalonia.Controls; using domain.Request; using domain.UseCase; using Presense.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.Text; using System.Threading.Tasks; namespace Presence.Desktop.ViewModels { public class GroupViewModel : ViewModelBase { private readonly IGroupUseCase _groupService; private readonly List _groupPresentersDataSource = new(); private ObservableCollection _groups; public ObservableCollection Groups => _groups; private GroupPresenter? _selectedGroupItem; public GroupPresenter? SelectedGroupItem { get => _selectedGroupItem; set { if (_selectedGroupItem != value) { _selectedGroupItem = value; this.RaisePropertyChanged(); UpdateStudents(); } } } private ObservableCollection _students; public ObservableCollection Students => _students; public GroupViewModel() : this(null!) { } public GroupViewModel(IGroupUseCase groupUseCase) { _groupService = groupUseCase; Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); ImportStudentsCommand = ReactiveCommand.CreateFromTask(ImportStudentsAsync); LoadGroupsAndStudents(); _students = new ObservableCollection(); RemoveAllStudentsCommand = ReactiveCommand.Create(RemoveAllStudents); RemoveSelectedStudentsCommand = ReactiveCommand.Create(RemoveSelectedStudents); } private void LoadGroupsAndStudents() { foreach (var groupEntity in _groupService.GetGroupsWithStudents()) { var groupPresenter = new GroupPresenter { GroupId = groupEntity.GroupId, GroupName = groupEntity.GroupName, Students = groupEntity.Students?.Select(student => new StudentPresenter { Id = student.Id, FirstName = student.FirstName, LastName = student.LastName, Patronymic = student.Patronymic, Group = null }).ToList(), Subjects = groupEntity.Subjects.Select(subject => new SubjectPresenter { SubjectId = subject.SubjectId, SubjectName = subject.SubjectName }).ToList() }; foreach (var student in groupPresenter.Students ?? Enumerable.Empty()) { student.Group = groupPresenter; } _groupPresentersDataSource.Add(groupPresenter); } _groups = new ObservableCollection(_groupPresentersDataSource); } private void UpdateStudents() { if (SelectedGroupItem?.Students == null) return; Students.Clear(); foreach (var student in SelectedGroupItem.Students) { Students.Add(student); } } private readonly string[] _sortingOptions = new[] { "Без сортировки", "Фамилии (по возрастанию)", "Фамилии (по убыванию)" }; public string[] SortingOptions => _sortingOptions; private string? _selectedSortingOption; public string? SelectedSortingOption { get => _selectedSortingOption; set { this.RaiseAndSetIfChanged(ref _selectedSortingOption, value); ApplySorting(); } } private void ApplySorting() { if (SelectedGroupItem?.Students == null) return; IEnumerable sortedStudents = SelectedSortingOption switch { "Фамилии (по возрастанию)" => SelectedGroupItem.Students.OrderBy(s => s.LastName), "Фамилии (по убыванию)" => SelectedGroupItem.Students.OrderByDescending(s => s.LastName), _ => SelectedGroupItem.Students }; Students.Clear(); foreach (var student in sortedStudents) { Students.Add(student); } } public ReactiveCommand RemoveAllStudentsCommand { get; } private void RemoveAllStudents() { if (SelectedGroupItem == null || SelectedGroupItem.Students == null) return; _groupService.RemoveStudentsFromGroup(SelectedGroupItem.GroupId); SelectedGroupItem.Students.Clear(); UpdateStudents(); LoadGroupsAndStudents(); } public ReactiveCommand ImportStudentsCommand { get; } public async Task ImportStudentsAsync() { var dialog = new OpenFileDialog { Title = "Выберите файл CSV:", Filters = new List { new FileDialogFilter { Name = "CSV Files", Extensions = { "csv" } } } }; var result = await dialog.ShowAsync(new Window()); if (result != null && result.Any()) { var filePath = result.First(); if (SelectedGroupItem == null) { Console.WriteLine("Группа не выбрана."); return; } try { var csvLines = File.ReadAllLines(filePath, Encoding.GetEncoding("windows-1251")); var studentsToAdd = new List(); foreach (var line in csvLines) { var data = line.Split(';'); if (data.Length != 3) { Console.WriteLine($"Либо разделитель либо хз: {line}"); continue; } studentsToAdd.Add(new AddStudentRequest { FirstName = data[0], LastName = data[1], Patronymic = data[2] }); } if (studentsToAdd.Any()) { _groupService.AddStudentsToGroup(SelectedGroupItem.GroupId, studentsToAdd); foreach (var studentRequest in studentsToAdd) { var studentPresenter = new StudentPresenter { FirstName = studentRequest.FirstName, LastName = studentRequest.LastName, Patronymic = studentRequest.Patronymic, Group = SelectedGroupItem }; SelectedGroupItem.Students.Add(studentPresenter); Students.Add(studentPresenter); } UpdateStudents(); LoadGroupsAndStudents(); } else { Console.WriteLine("Проблема с данными."); } } catch (Exception ex) { Console.WriteLine($"...: {ex.Message}"); } } } private ObservableCollection _selectedStudents = new(); public ObservableCollection SelectedStudents { get => _selectedStudents; set { this.RaiseAndSetIfChanged(ref _selectedStudents, value); UpdateSelectionStates(); } } private bool _isSingleSelection; public bool IsSingleSelection { get => _isSingleSelection; set => this.RaiseAndSetIfChanged(ref _isSingleSelection, value); } private bool _isMultipleSelection; public bool IsMultipleSelection { get => _isMultipleSelection; set => this.RaiseAndSetIfChanged(ref _isMultipleSelection, value); } public void UpdateSelectionStates() { IsSingleSelection = SelectedStudents.Count == 1; IsMultipleSelection = SelectedStudents.Count > 1; } public ReactiveCommand RemoveSelectedStudentsCommand { get; } private void RemoveSelectedStudents() { if (SelectedStudents == null || SelectedStudents.Count == 0) return; var studentIds = SelectedStudents.Select(s => s.Id).ToList(); _groupService.RemoveStudentsFromGroupByIds(SelectedGroupItem.GroupId, studentIds); foreach (var student in SelectedStudents.ToList()) { SelectedGroupItem.Students.Remove(student); Students.Remove(student); } UpdateStudents(); LoadGroupsAndStudents(); } } }