namespace SteUp.Shared.Core.Messages.System;
///
/// Ponte fra il tasto indietro del dispositivo (host nativo) e la UI Blazor.
/// Il form scheda si registra mentre è aperto così il back non manda l'app in
/// background buttando via il lavoro non salvato: passa invece dallo stesso
/// percorso del pulsante "Annulla", che propone il salvataggio come bozza.
///
/// I gestori sono impilati: sopra il form può aprirsi un bottom sheet, e il
/// tasto indietro deve chiudere prima quello. Chiudendolo si torna al gestore
/// sottostante, che resta valido — senza la pila il sheet, uscendo di scena,
/// porterebbe via con sé anche la registrazione del form.
///
public class BackButtonService
{
private readonly List> _handlers = [];
///
/// Segnala all'host se in questo momento c'è qualcuno da avvisare. L'host
/// se ne serve per accendere e spegnere la propria intercettazione, così
/// quando la UI non ha nulla da dire il tasto indietro torna a comportarsi
/// esattamente come sempre.
///
public event Action? HandlersChanged;
public bool HasHandlers => _handlers.Count > 0;
/// Registra il gestore corrente in cima alla pila. Ritorna la deregistrazione.
public IDisposable Register(Func handler)
{
_handlers.Add(handler);
HandlersChanged?.Invoke(true);
return new Registration(this, handler);
}
///
/// Invocato dall'host nativo. Ritorna true se la UI Blazor ha preso in carico
/// il tasto indietro: in quel caso l'host non deve fare altro.
///
public bool TryHandleBackPressed()
{
if (_handlers.Count == 0) return false;
// Fire-and-forget: il gestore rientra nel dispatcher Blazor da solo.
_ = _handlers[^1]();
return true;
}
private sealed class Registration(BackButtonService owner, Func handler) : IDisposable
{
public void Dispose()
{
if (!owner._handlers.Remove(handler)) return;
owner.HandlersChanged?.Invoke(owner.HasHandlers);
}
}
}