using EnvelopeGenerator.ReceiverUI.Client.Models;
namespace EnvelopeGenerator.ReceiverUI.Client.State;
///
/// Hält den aktuellen Zustand des geladenen Umschlags.
///
/// WARUM ein eigenes State-Objekt?
/// - Mehrere Komponenten auf einer Seite brauchen die gleichen Daten
/// - Ohne State müsste jede Komponente die Daten selbst laden → doppelte API-Calls
/// - StateHasChanged() informiert automatisch alle Subscriber
///
/// PATTERN: "Observable State" — Services setzen den State, Komponenten reagieren darauf.
///
/// Die Set-Methoden nehmen jetzt ein ReceiverAuthModel entgegen,
/// damit alle Felder (Title, SenderEmail, TfaType etc.) zentral gespeichert werden.
///
public class EnvelopeState
{
private EnvelopePageStatus _status = EnvelopePageStatus.Loading;
/// Aktueller Seitenstatus
public EnvelopePageStatus Status
{
get => _status;
private set
{
_status = value;
NotifyStateChanged();
}
}
// ── Felder aus ReceiverAuthModel ──
/// Titel des Umschlags (z.B. "Vertragsdokument")
public string? Title { get; private set; }
/// Nachricht des Absenders
public string? Message { get; private set; }
/// E-Mail des Absenders (für Rückfragen-Hinweis)
public string? SenderEmail { get; private set; }
/// Ob TFA für diesen Umschlag aktiviert ist
public bool TfaEnabled { get; private set; }
/// Ob der Empfänger eine Telefonnummer hat (für SMS-TFA)
public bool HasPhoneNumber { get; private set; }
/// Ob das Dokument nur gelesen werden soll (ReadAndConfirm)
public bool ReadOnly { get; private set; }
/// TFA-Typ: "sms" oder "authenticator"
public string? TfaType { get; private set; }
/// Ablaufzeit des SMS-Codes (für Countdown-Timer)
public DateTime? TfaExpiration { get; private set; }
/// Fehlermeldung (z.B. "Falscher Zugangscode")
public string? ErrorMessage { get; private set; }
// ── Zustandsübergänge ──
public void SetLoading()
{
ErrorMessage = null;
Status = EnvelopePageStatus.Loading;
}
///
/// Setzt den State aus einer API-Antwort.
/// Zentrale Methode — alle Endpunkte liefern ReceiverAuthModel,
/// und diese Methode mappt den Status-String auf das richtige Enum.
///
public void ApplyApiResponse(ReceiverAuthModel model)
{
// Gemeinsame Felder immer übernehmen
Title = model.Title ?? Title;
Message = model.Message ?? Message;
SenderEmail = model.SenderEmail ?? SenderEmail;
TfaEnabled = model.TfaEnabled;
HasPhoneNumber = model.HasPhoneNumber;
ReadOnly = model.ReadOnly;
TfaType = model.TfaType ?? TfaType;
TfaExpiration = model.TfaExpiration ?? TfaExpiration;
ErrorMessage = model.ErrorMessage;
// Status-String → Enum
Status = model.Status switch
{
"requires_access_code" => EnvelopePageStatus.RequiresAccessCode,
"requires_tfa" => EnvelopePageStatus.RequiresTwoFactor,
"show_document" => EnvelopePageStatus.ShowDocument,
"already_signed" => EnvelopePageStatus.AlreadySigned,
"rejected" => EnvelopePageStatus.Rejected,
"not_found" => EnvelopePageStatus.NotFound,
"expired" => EnvelopePageStatus.Expired,
"error" => EnvelopePageStatus.Error,
_ => EnvelopePageStatus.Error
};
}
/// Setzt Fehler wenn der API-Call selbst fehlschlägt (Netzwerk etc.)
public void SetError(string message)
{
ErrorMessage = message;
Status = EnvelopePageStatus.Error;
}
/// Setzt NotFound (z.B. bei 404 ohne Body)
public void SetNotFound() => Status = EnvelopePageStatus.NotFound;
// ── Event ──
public event Action? OnChange;
private void NotifyStateChanged() => OnChange?.Invoke();
}
/// Alle möglichen Zustände der Umschlag-Seite
public enum EnvelopePageStatus
{
Loading,
RequiresAccessCode,
RequiresTwoFactor,
ShowDocument,
AlreadySigned,
Rejected,
NotFound,
Expired,
Error
}