import 'dart:async';

import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../api/endpoints/requests.dart';
import '../cache/mutation_queue.dart';
import '../library/library_providers.dart' show dioProvider;
import '../models/admin_request.dart';

final requestsApiProvider = FutureProvider<RequestsApi>((ref) async {
  return RequestsApi(await ref.watch(dioProvider.future));
});

/// Mirrors the web's createMyRequestsQuery auto-poll (#369): refresh
/// every 12s while any row is mid-ingest (status='approved'), stop when
/// all rows settle. Polls regardless of app foreground/background — a
/// future enhancement could pause via WidgetsBindingObserver, but for
/// v1 the small extra refresh is acceptable.
class MyRequestsController extends AsyncNotifier<List<AdminRequest>> {
  static const Duration _pollInterval = Duration(seconds: 12);

  Timer? _pollTimer;

  @override
  Future<List<AdminRequest>> build() async {
    ref.onDispose(() {
      _pollTimer?.cancel();
      _pollTimer = null;
    });
    final api = await ref.watch(requestsApiProvider.future);
    final rows = await api.listMine();
    _maybeStartPolling(rows);
    return rows;
  }

  void _maybeStartPolling(List<AdminRequest> rows) {
    _pollTimer?.cancel();
    if (rows.any((r) => r.status == 'approved')) {
      _pollTimer = Timer.periodic(_pollInterval, (_) {
        ref.invalidateSelf();
      });
    }
  }

  /// Optimistic remove + REST cancel. On failure the row stays
  /// removed in-memory and the cancel is queued for replay — this
  /// keeps the user's intent visible across network loss instead of
  /// restoring a row they explicitly asked to remove.
  Future<void> cancel(String id) async {
    final api = await ref.read(requestsApiProvider.future);
    final current = state.value ?? const <AdminRequest>[];
    state = AsyncData(current.where((r) => r.id != id).toList());
    try {
      await api.cancel(id);
    } catch (_) {
      await ref
          .read(mutationQueueProvider)
          .enqueue(MutationKinds.requestCancel, {'id': id});
    }
  }
}

final myRequestsProvider =
    AsyncNotifierProvider<MyRequestsController, List<AdminRequest>>(
        MyRequestsController.new);
