import 'dart:async';

import 'package:flutter/services.dart';

import '../state/app/modules/settings/bloc/settings_cubit.dart';
import '../storage/haptic_settings.dart';
import '../storage/settings.dart';

/// App-weite Haptik-Fassade. Liest die aktive Stufe aus einem in-memory Cache,
/// der einmal an den SettingsCubit gebunden wird — damit sind die Aufrufe
/// kontextfrei (egal ob aus Widget oder Util).
///
/// Semantische Methoden statt roher Impacts, damit Call-Sites die Intention
/// transportieren, nicht die Stärke.
class Haptics {
  static HapticLevel _level = HapticLevel.full;
  static StreamSubscription<Settings>? _sub;

  /// Einmal aus App-Root aufrufen, sobald der [SettingsCubit] verfügbar ist.
  static void bind(SettingsCubit cubit) {
    _level = cubit.state.hapticSettings.level;
    _sub?.cancel();
    _sub = cubit.stream.listen((s) => _level = s.hapticSettings.level);
  }

  // --- reduced + full ---

  /// Long-Press, der ein Bottom-Sheet / Action-Menü öffnet.
  static void longPress() {
    if (_level == HapticLevel.off) return;
    HapticFeedback.mediumImpact();
  }

  /// Bestätigen eines ConfirmDialogs (nicht das Abbrechen).
  static void confirm() {
    if (_level == HapticLevel.off) return;
    HapticFeedback.mediumImpact();
  }

  /// Fehler einer Async-Aktion / Dialog-Fehler.
  static void error() {
    if (_level == HapticLevel.off) return;
    HapticFeedback.mediumImpact();
  }

  /// Seltener Dopamin-Moment — z.B. erfolgreicher Login.
  static void heavyAccent() {
    if (_level == HapticLevel.off) return;
    HapticFeedback.heavyImpact();
  }

  // --- nur full ---

  /// Erfolg einer Async-Aktion (Senden, Reagieren, Speichern, …).
  static void success() {
    if (_level != HapticLevel.full) return;
    HapticFeedback.lightImpact();
  }

  /// Pull-to-Refresh ausgelöst.
  static void refresh() {
    if (_level != HapticLevel.full) return;
    HapticFeedback.selectionClick();
  }

  /// Tab-Wechsel, Toggle-Switch, Clipboard-Copy — alles, was eine
  /// subtile Quittung verdient.
  static void selection() {
    if (_level != HapticLevel.full) return;
    HapticFeedback.selectionClick();
  }
}
