// lib/remote/remote_sync_bus.dart
import 'package:flutter/foundation.dart';

enum RemoteSyncState {
  disabled,
  syncing,
  upToDate,
  timeout,
  networkError,
  badGateway,
  serverError,
  serverDown,
}

class RemoteSyncProgress {
  final int done;
  final int total;
  final bool showOverlay;

  const RemoteSyncProgress({
    required this.done,
    required this.total,
    this.showOverlay = false,
  });
}

class RemoteSyncBus {
  RemoteSyncBus._();
  static final RemoteSyncBus instance = RemoteSyncBus._();

  final ValueNotifier<RemoteSyncState> stateNotifier =
      ValueNotifier(RemoteSyncState.disabled);

  final ValueNotifier<RemoteSyncProgress?> progressNotifier =
      ValueNotifier(null);

  int _opId = 0;

  int nextOp() => ++_opId;
  bool _isStale(int opId) => opId != _opId;

  void setDisabled() {
    _opId++;
    stateNotifier.value = RemoteSyncState.disabled;
    progressNotifier.value = null;
  }

  int start({required int total, required bool showOverlay}) {
    final opId = nextOp();
    stateNotifier.value = RemoteSyncState.syncing;
    progressNotifier.value = RemoteSyncProgress(
      done: 0,
      total: total,
      showOverlay: showOverlay,
    );
    return opId;
  }

  void update({required int opId, required int done, required int total}) {
    if (_isStale(opId)) return;
    final cur = progressNotifier.value;
    progressNotifier.value = RemoteSyncProgress(
      done: done,
      total: total,
      showOverlay: cur?.showOverlay ?? false,
    );
  }

  void finishUpToDate({required int opId}) {
    if (_isStale(opId)) return;
    stateNotifier.value = RemoteSyncState.upToDate;
    progressNotifier.value = null;
  }

  void failTimeout({required int opId}) {
    if (_isStale(opId)) return;
    stateNotifier.value = RemoteSyncState.timeout;
    progressNotifier.value = null;
  }

  void failNetwork({required int opId}) {
    if (_isStale(opId)) return;
    stateNotifier.value = RemoteSyncState.networkError;
    progressNotifier.value = null;
  }

  void failBadGateway({required int opId}) {
    if (_isStale(opId)) return;
    stateNotifier.value = RemoteSyncState.badGateway;
    progressNotifier.value = null;
  }

  void failServerError({required int opId}) {
    if (_isStale(opId)) return;
    stateNotifier.value = RemoteSyncState.serverError;
    progressNotifier.value = null;
  }

  void failServerDown({required int opId}) {
    if (_isStale(opId)) return;
    stateNotifier.value = RemoteSyncState.serverDown;
    progressNotifier.value = null;
  }
}
