import 'package:matrix/matrix.dart';
import 'package:pyramid/core/auth_log.dart';

/// Wendet einen Soft-Logout durch Token-Refresh ab, ohne JE in einen
/// destruktiven Logout zu eskalieren.
///
/// Hintergrund: Ohne gesetztes `Client.onSoftLogout` behandelt das matrix-SDK
/// einen fehlgeschlagenen Refresh so: catch → `logout()` → `finally clear()` —
/// die lokale Session inkl. Krypto-Schlüssel wird also selbst dann zerstört,
/// wenn der Refresh nur an einem transienten Netzwerkfehler scheiterte
/// (Gerät offline im Moment des Token-Ablaufs) oder am Rotations-Race mit dem
/// Push-Hintergrund-Isolate (beide teilen sich die DB; refreshAccessToken()
/// liest den Refresh-Token bei jedem Versuch frisch aus der DB, deshalb heilt
/// ein Retry dieses Race). Wirft dieser Handler nicht, ruft das SDK auch kein
/// `logout()` auf (Client._handleSoftLogout, matrix 6.2.0).
///
/// Regel aus CLAUDE.md: Fehlerpfade dürfen NIE in einem stillen Logout enden.
/// Schlägt der Refresh dauerhaft fehl, bleibt der Client im Zustand
/// soft-logged-out; der nächste Sync/API-Aufruf stößt den Refresh erneut an.
Future<void> guardedSoftLogoutRefresh(Client client) async {
  for (var attempt = 1; attempt <= 3; attempt++) {
    try {
      await client.refreshAccessToken();
      await AuthLog.write(
        'Soft-Logout durch Token-Refresh abgewendet (Versuch $attempt)',
      );
      return;
    } catch (e) {
      await AuthLog.write(
        'Soft-Logout: Token-Refresh fehlgeschlagen (Versuch $attempt/3): $e',
      );
      if (attempt < 3) {
        await Future.delayed(Duration(seconds: 2 * attempt));
      }
    }
  }
  await AuthLog.write(
    'Soft-Logout: Refresh dauerhaft fehlgeschlagen – Session wird NICHT '
    'zerstört, nächster Sync/API-Aufruf versucht es erneut.',
  );
}
