using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using LehrerApp.Core.Interfaces; using LehrerApp.Core.Models; using LehrerApp.Core.Services; using LehrerApp.Data; using LehrerApp.Desktop.Services; using LehrerApp.Desktop.ViewModels.Planning; using LehrerApp.Sync; using LehrerApp.Sync.Crypto; using System.Collections.ObjectModel; using System.Globalization; using System.Security.Cryptography; using System.Text.Json; using System.Text.Json.Serialization; namespace LehrerApp.Desktop.ViewModels.Settings; public partial class SettingsViewModel { // ── Sicherheit: Datensicherung (13.3.1/13.3.2) ─────────────────────────── [ObservableProperty] private string _backupStatus = ""; [ObservableProperty] private string _secondaryBackupDirectory = ""; public ObservableCollection Backups { get; } = []; /// Vom Code-Behind gesetzt: zeigt einen Bestätigungsdialog vor dem Wiederherstellen. public Func>? OnConfirmRestore { get; set; } /// Vom Code-Behind gesetzt: öffnet einen Ordnerauswahl-Dialog für das zweite Sicherungsziel. public Func>? OnPickBackupDirectory { get; set; } // ── Datensicherung: Laden / Erstellen / Wiederherstellen ───────────────── private void LoadBackups() { Backups.Clear(); foreach (var b in _backups.ListBackups()) Backups.Add(new BackupListItem(b)); SecondaryBackupDirectory = _backupSettings.LoadSecondaryDirectory() ?? ""; } [RelayCommand] private void CreateBackupNow() { var path = _backups.CreateBackup(AppBootstrapper.DbPath); LoadBackups(); if (path is null) { BackupStatus = "Kein Backup erstellt (Datenbankdatei fehlt)."; return; } BackupStatus = _dbEncryption.CanOpenAndRead(path, AppBootstrapper.DbPassword) ? "Backup erstellt und geprüft." : "Backup erstellt — Prüfung fehlgeschlagen, Datei könnte beschädigt sein!"; } [RelayCommand] private async Task PickBackupDirectory() { if (OnPickBackupDirectory is null) return; var path = await OnPickBackupDirectory(); if (path is null) return; _backupSettings.SaveSecondaryDirectory(path); _backups.SecondaryBackupDirectory = path; SecondaryBackupDirectory = path; BackupStatus = "Zweiter Sicherungsordner gespeichert."; } [RelayCommand] private void ClearBackupDirectory() { _backupSettings.SaveSecondaryDirectory(null); _backups.SecondaryBackupDirectory = null; SecondaryBackupDirectory = ""; BackupStatus = "Zweiter Sicherungsordner entfernt."; } [RelayCommand] private async Task RestoreBackup(BackupListItem? item) { if (item is null) return; if (OnConfirmRestore is not null && !await OnConfirmRestore(item)) return; _dbContext.Dispose(); _backups.RestoreBackup(item.Path, AppBootstrapper.DbPath); AppBootstrapper.RestartApplication(); } } public class BackupListItem(BackupInfo info) { public string Path { get; } = info.Path; public string Display { get; } = $"{info.CreatedAt:dd.MM.yyyy HH:mm} · {info.SizeBytes / 1024.0:0} KB"; }