using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using LehrerApp.Core.Interfaces; using LehrerApp.Core.Models; using LehrerApp.Desktop.ViewModels.Students; using System.Collections.ObjectModel; namespace LehrerApp.Desktop.ViewModels.Groups; /// /// Gruppen-Tab "Dokumentation" (bisher Platzhalter): zeigt die Dokumentationseinträge aller /// aktuellen/ehemaligen Schüler dieser Gruppe an einem Ort, statt sie einzeln im Schüler-Tab /// aufsuchen zu müssen. Nutzer-Feedback: die Liste soll standardmäßig auch Einträge aus anderen /// Lerngruppen desselben Schülers mit anzeigen (optisch abgesetzt statt ausgeblendet), damit /// Muster aus anderen Fächern/Kursen nicht verborgen bleiben — ein Schalter blendet sie bei /// Bedarf ganz aus. /// public partial class GroupDocumentationTabViewModel : ObservableObject { private readonly IDocumentationRepository _docs; private readonly IStudentRepository _students; private readonly IGroupRepository _groups; private Guid _groupId; private List _groupStudents = []; public static readonly StudentOption AllStudentsOption = new(Guid.Empty, "Alle Schüler"); public static readonly StudentOption WholeGroupOption = new(Guid.Empty, "Gesamte Lerngruppe"); public ObservableCollection Entries { get; } = []; public ObservableCollection StudentFilterOptions { get; } = [AllStudentsOption]; [ObservableProperty] private StudentOption _selectedStudentFilter = AllStudentsOption; [ObservableProperty] private bool _onlyThisGroup; [ObservableProperty] private int _draftCount; public Func, Documentation?, Task>? OnEditDocumentation { get; set; } public Func>? OnConfirmDeleteDocumentation { get; set; } public Func>? OnConductParentCall { get; set; } public GroupDocumentationTabViewModel(IDocumentationRepository docs, IStudentRepository students, IGroupRepository groups) { _docs = docs; _students = students; _groups = groups; } partial void OnSelectedStudentFilterChanged(StudentOption value) => Load(); partial void OnOnlyThisGroupChanged(bool value) => Load(); public void Initialize(Guid groupId) { _groupId = groupId; _groupStudents = _students.GetByGroup(groupId) .Select(s => new StudentOption(s.Id, s.FullName)).ToList(); StudentFilterOptions.Clear(); StudentFilterOptions.Add(AllStudentsOption); foreach (var s in _groupStudents) StudentFilterOptions.Add(s); SelectedStudentFilter = AllStudentsOption; Load(); } private void Load() { Entries.Clear(); var studentNameById = _groupStudents.ToDictionary(s => s.Id, s => s.Name); var groupNameCache = new Dictionary(); string GroupLabel(Guid id) { if (groupNameCache.TryGetValue(id, out var cached)) return cached; var label = _groups.GetById(id)?.Name ?? ""; groupNameCache[id] = label; return label; } var relevantStudentIds = SelectedStudentFilter.Id == Guid.Empty ? _groupStudents.Select(s => s.Id) : [SelectedStudentFilter.Id]; var all = relevantStudentIds .SelectMany(id => _docs.GetByStudent(id)) .Concat(SelectedStudentFilter.Id == Guid.Empty ? _docs.GetAll().Where(d => d.StudentId == Guid.Empty && d.GroupId == _groupId) : []) .DistinctBy(d => d.Id) .Where(d => !OnlyThisGroup || d.GroupId == _groupId) .OrderByDescending(d => d.IsDraft) .ThenByDescending(d => d.Date) .ToList(); DraftCount = all.Count(d => d.IsDraft && (d.GroupId is null || d.GroupId == _groupId)); foreach (var d in all) { var isOwnGroup = d.GroupId is null || d.GroupId == _groupId; var otherGroupLabel = isOwnGroup ? "" : GroupLabel(d.GroupId!.Value); var studentName = d.StudentId == Guid.Empty ? WholeGroupOption.Name : studentNameById.GetValueOrDefault(d.StudentId, ""); Entries.Add(new DocumentationItem(d, studentName, isOwnGroup, otherGroupLabel)); } } public void Refresh() => Load(); [RelayCommand] private async Task AddDocumentation() { if (OnEditDocumentation is null) return; var result = await OnEditDocumentation(_groupId, _groupStudents, null); if (result is null) return; _docs.Save(result); Load(); } [RelayCommand] private async Task EditDocumentation(DocumentationItem? item) { if (item is null || OnEditDocumentation is null) return; var result = await OnEditDocumentation(_groupId, _groupStudents, item.Model); if (result is null) return; _docs.Save(result); Load(); } [RelayCommand] private async Task DeleteDocumentation(DocumentationItem? item) { if (item is null) return; if (OnConfirmDeleteDocumentation is not null && !await OnConfirmDeleteDocumentation(item)) return; _docs.Delete(item.Model.Id); Load(); } [RelayCommand] private async Task ConductParentCall(DocumentationItem? item) { if (item is null || OnConductParentCall is null) return; var result = await OnConductParentCall(item.Model, item.StudentName); if (result is null) return; _docs.Save(result); Load(); } }