using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using LehrerApp.Data; using LehrerApp.Sync; using LehrerApp.Sync.Models; namespace LehrerApp.Desktop.ViewModels; /// /// Steuert den Dialog zum Einrichten eines neuen Geräts. /// /// Zwei Modi: /// Sender → "Neues Gerät hinzufügen" – erzeugt Snapshot und zeigt Code /// Empfänger → "Mit bestehendem Account verbinden" – Code eingeben, Restore /// public partial class DevicePairingViewModel : ObservableObject { private readonly SnapshotService _snapshotService; // ── Gemeinsamer State ───────────────────────────────────────────────────── [ObservableProperty] private PairingMode _mode = PairingMode.SelectMode; [ObservableProperty] private bool _isBusy; [ObservableProperty] private string _statusMessage = ""; [ObservableProperty] private int _progressPercent; [ObservableProperty] private bool _isError; [ObservableProperty] private bool _isComplete; // ── Sender-State ───────────────────────────────────────────────────────── [ObservableProperty] private string _generatedCode = ""; [ObservableProperty] private DateTime _codeExpiresAt; [ObservableProperty] private string _codeExpiresText = ""; // ── Empfänger-State ─────────────────────────────────────────────────────── [ObservableProperty] private string _inputCode = ""; public DevicePairingViewModel(SnapshotService snapshotService) { _snapshotService = snapshotService; _snapshotService.ProgressChanged += OnProgress; } // ── Navigation zwischen Modi ────────────────────────────────────────────── [RelayCommand] private void SelectSender() => Mode = PairingMode.Sender; [RelayCommand] private void SelectReceiver() => Mode = PairingMode.Receiver; [RelayCommand] private void Back() { Mode = PairingMode.SelectMode; Reset(); } // ── Sender: Snapshot erstellen ──────────────────────────────────────────── [RelayCommand(CanExecute = nameof(CanCreateSnapshot))] private async Task CreateSnapshotAsync() { IsBusy = true; IsError = false; IsComplete = false; try { var result = await _snapshotService.CreateAndUploadAsync(); GeneratedCode = result.Code; CodeExpiresAt = result.ExpiresAt; CodeExpiresText = $"Gültig bis {result.ExpiresAt:HH:mm} Uhr " + $"({result.ExpiresAt:dd.MM.yyyy})"; Mode = PairingMode.SenderShowCode; } catch (Exception ex) { IsError = true; StatusMessage = $"Fehler: {ex.Message}"; } finally { IsBusy = false; } } private bool CanCreateSnapshot() => !IsBusy; // ── Empfänger: Snapshot wiederherstellen ────────────────────────────────── [RelayCommand(CanExecute = nameof(CanRestore))] private async Task RestoreAsync(string targetDbPath) { IsBusy = true; IsError = false; IsComplete = false; try { // Schlüssel wird aus dem Code extrahiert und lokal gespeichert // → App-Neustart lädt ihn automatisch await _snapshotService.RestoreFromCodeAsync( InputCode.Trim(), targetDbPath); IsComplete = true; StatusMessage = "Erfolgreich! Bitte die App neu starten."; Mode = PairingMode.ReceiverDone; } catch (SnapshotNotFoundException ex) { IsError = true; StatusMessage = ex.Message; } catch (Exception ex) { IsError = true; StatusMessage = $"Fehler beim Wiederherstellen: {ex.Message}"; } finally { IsBusy = false; } } private bool CanRestore() => !IsBusy && InputCode.Trim().Length >= 5; // ── Hilfsmethoden ───────────────────────────────────────────────────────── private void OnProgress(SnapshotProgress progress) { StatusMessage = progress.Message; ProgressPercent = progress.PercentComplete; } private void Reset() { StatusMessage = ""; ProgressPercent = 0; IsError = false; IsComplete = false; GeneratedCode = ""; InputCode = ""; IsBusy = false; } } public enum PairingMode { SelectMode, // Startbildschirm: Sender oder Empfänger wählen Sender, // Sender bereit, Snapshot erstellen SenderShowCode, // Code wird angezeigt Receiver, // Code-Eingabe ReceiverDone, // Erfolgreich wiederhergestellt }