import 'dart:async';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../api/api_client_provider.dart';

part 'status_notifier.g.dart';

// States
sealed class OnlineStatusData {
  const OnlineStatusData();
}

class StatusInitialData extends OnlineStatusData {
  const StatusInitialData();
}

class StatusLoadedData extends OnlineStatusData {
  final bool isOnline;
  const StatusLoadedData({required this.isOnline});
}

class StatusLoadingData extends OnlineStatusData {
  const StatusLoadingData();
}

class StatusErrorData extends OnlineStatusData {
  final String message;
  const StatusErrorData(this.message);
}

@Riverpod(keepAlive: true)
class OnlineStatus extends _$OnlineStatus {
  Timer? _heartbeatTimer;
  bool _requirePing = true;
  int _pingIntervalSeconds = 15;

  @override
  OnlineStatusData build() => const StatusInitialData();

  Future<void> load() async {
    try {
      final response = await ref.read(apiClientProvider).get('/api/mitra/status');
      final data = response['data'] as Map<String, dynamic>;
      _requirePing = data['require_ping'] as bool? ?? true;
      _pingIntervalSeconds = data['ping_interval_seconds'] as int? ?? 15;
      state = StatusLoadedData(isOnline: data['is_online'] as bool);
    } catch (e) {
      state = const StatusLoadedData(isOnline: false);
    }
  }

  Future<void> toggleOnline() async {
    state = const StatusLoadingData();
    try {
      await ref.read(apiClientProvider).post('/api/mitra/status/online');
      if (_requirePing) _startHeartbeat();
      state = const StatusLoadedData(isOnline: true);
    } catch (e) {
      state = const StatusErrorData('Gagal mengubah status. Coba lagi.');
    }
  }

  Future<void> toggleOffline() async {
    state = const StatusLoadingData();
    try {
      await ref.read(apiClientProvider).post('/api/mitra/status/offline');
      _stopHeartbeat();
      state = const StatusLoadedData(isOnline: false);
    } catch (e) {
      state = const StatusErrorData('Gagal mengubah status. Coba lagi.');
    }
  }

  void onAppPaused() {
    if (_requirePing) _stopHeartbeat();
  }

  void onAppResumed() {
    if (_requirePing && state is StatusLoadedData && (state as StatusLoadedData).isOnline) {
      _startHeartbeat();
    }
    load();
  }

  void _startHeartbeat() {
    _stopHeartbeat();
    _heartbeatTimer = Timer.periodic(Duration(seconds: _pingIntervalSeconds), (_) {
      _heartbeatTick();
    });
  }

  void _stopHeartbeat() {
    _heartbeatTimer?.cancel();
    _heartbeatTimer = null;
  }

  Future<void> _heartbeatTick() async {
    try {
      await ref.read(apiClientProvider).post('/api/mitra/status/heartbeat');
    } catch (_) {}
  }
}
