import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../../core/config/app_config.dart';
import '../../../../core/services/notification_service.dart';
import '../../domain/entities/app_notification.dart';
import '../../data/in_site_notification.dart';
import '../../data/in_site_notification_repository.dart';

/// Global local notifications plugin instance (initialized in main.dart).
final localNotificationsPluginProvider =
    Provider<FlutterLocalNotificationsPlugin>((ref) {
  return FlutterLocalNotificationsPlugin();
});

/// Notification service singleton.
final notificationServiceProvider = Provider<NotificationService>((ref) {
  final config = ref.watch(appConfigProvider);
  final plugin = ref.watch(localNotificationsPluginProvider);
  return NotificationService(
    baseUrl: config.apiBaseUrl,
    localNotifications: plugin,
  );
});

/// Accumulated push notification list (local/realtime).
class NotificationListNotifier extends StateNotifier<List<AppNotification>> {
  NotificationListNotifier() : super([]);

  void add(AppNotification notification) {
    state = [notification, ...state];
  }

  void markRead(String id) {
    state = state.map((n) {
      if (n.id == id) return n.copyWith(isRead: true);
      return n;
    }).toList();
  }

  void markAllRead() {
    state = state.map((n) => n.copyWith(isRead: true)).toList();
  }

  void clear() {
    state = [];
  }
}

final notificationListProvider =
    StateNotifierProvider<NotificationListNotifier, List<AppNotification>>(
        (ref) {
  return NotificationListNotifier();
});

/// Local push notification unread count.
final unreadNotificationCountProvider = Provider<int>((ref) {
  final notifications = ref.watch(notificationListProvider);
  return notifications.where((n) => !n.isRead).length;
});

// ── In-site (站内消息) notification providers ──────────────────────────────

/// Polls the backend every 30s for the unread in-site notification count.
final inSiteUnreadCountProvider = StreamProvider<int>((ref) async* {
  final repo = ref.watch(inSiteNotificationRepositoryProvider);

  Future<int> fetch() async {
    try {
      return await repo.getUnreadCount();
    } catch (_) {
      return 0;
    }
  }

  // Emit immediately on first build
  yield await fetch();

  // Then poll every 30s
  await for (final _ in Stream.periodic(const Duration(seconds: 30))) {
    yield await fetch();
  }
});

/// Fetches the full in-site notification list (on demand, refreshed when invalidated).
final inSiteNotificationsProvider =
    FutureProvider<List<InSiteNotification>>((ref) async {
  final repo = ref.watch(inSiteNotificationRepositoryProvider);
  final result = await repo.getMyNotifications(limit: 100);
  return result.items;
});
