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 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();
if (_groupStudents.Count == 0) return;
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))
.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);
Entries.Add(new DocumentationItem(d, studentNameById.GetValueOrDefault(d.StudentId, ""),
isOwnGroup, otherGroupLabel));
}
}
public void Refresh() => Load();
[RelayCommand]
private async Task AddDocumentation()
{
if (OnEditDocumentation is null || _groupStudents.Count == 0) 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();
}
}