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

part 'mitra_availability_notifier.g.dart';

/// Customer-home availability poll.
///
/// Polls `GET /api/public/bestie/available` every 5 seconds while the home
/// screen is in the foreground. The endpoint is unauthenticated by design —
/// SHome1st renders before any JWT exists, and the CTA's enabled state needs
/// to reflect global availability so users see whether bestie is online
/// before committing to onboarding. Polling is gated by the home screen
/// calling [setActive] from `WidgetsBindingObserver.didChangeAppLifecycleState`:
///   - resumed   → setActive(true)
///   - paused/inactive → setActive(false)
///
/// On any HTTP error we emit `false` (never display stale state).
@Riverpod(keepAlive: true)
class MitraAvailability extends _$MitraAvailability {
  Timer? _pollTimer;
  bool _active = false;

  @override
  Future<bool> build() async {
    ref.onDispose(_stopPolling);
    // Default to disabled until the first poll returns. Never optimistically
    // show the CTA as enabled.
    return false;
  }

  /// Called by the home screen via `WidgetsBindingObserver` to gate polling
  /// to the foregrounded state. Polling is paused on `paused` / `inactive`
  /// and resumed on `resumed` (and an immediate poll fires on resume).
  void setActive(bool active) {
    if (_active == active) return;
    _active = active;
    if (_active) {
      _startPolling();
      // Fire-and-forget an immediate poll on resume so the CTA reflects
      // current availability without waiting up to 5s.
      // ignore: unawaited_futures
      _pollOnce();
    } else {
      _stopPolling();
    }
  }

  /// Manual one-shot refresh — used for pull-to-refresh on the home screen.
  Future<void> refresh() => _pollOnce();

  void _startPolling() {
    _stopPolling();
    _pollTimer = Timer.periodic(const Duration(seconds: 5), (_) => _pollOnce());
  }

  void _stopPolling() {
    _pollTimer?.cancel();
    _pollTimer = null;
  }

  Future<void> _pollOnce() async {
    bool available;
    try {
      final api = ref.read(apiClientProvider);
      final response = await api.get(
        '/api/public/bestie/available',
        skipAuth: true,
      );
      final data = response['data'] as Map<String, dynamic>?;
      available = data?['available'] as bool? ?? false;
    } catch (_) {
      // Poll failure → default to disabled. Never keep the last-known state.
      available = false;
    }
    // Skip the assignment when the value didn't change — Riverpod allocates a
    // new AsyncData each call, which would re-notify all listeners every 5s.
    if (state.valueOrNull == available) return;
    state = AsyncData(available);
  }
}
