import 'dart:async';

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:real_estate_mobile/features/notifications/data/models/notification_model.dart';
import 'package:real_estate_mobile/features/notifications/data/notification_repository.dart';

/// Unread notification count — polled every 30 seconds.
final unreadCountProvider =
    StateNotifierProvider<UnreadCountNotifier, int>((ref) {
  return UnreadCountNotifier(NotificationRepository());
});

class UnreadCountNotifier extends StateNotifier<int> {
  final NotificationRepository _repo;
  Timer? _timer;

  UnreadCountNotifier(this._repo) : super(0) {
    refresh();
    _timer = Timer.periodic(const Duration(seconds: 30), (_) => refresh());
  }

  Future<void> refresh() async {
    try {
      final count = await _repo.getUnreadCount();
      if (mounted) state = count;
    } catch (_) {
      // Silently fail — badge just won't update
    }
  }

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }
}

/// Notification list state.
class NotificationListState {
  final List<AppNotification> notifications;
  final bool isLoading;
  final bool isLoadingMore;
  final String? error;
  final String filter; // 'all' | 'unread'
  final int currentPage;
  final int totalPages;

  const NotificationListState({
    this.notifications = const [],
    this.isLoading = false,
    this.isLoadingMore = false,
    this.error,
    this.filter = 'all',
    this.currentPage = 1,
    this.totalPages = 1,
  });

  NotificationListState copyWith({
    List<AppNotification>? notifications,
    bool? isLoading,
    bool? isLoadingMore,
    String? error,
    String? filter,
    int? currentPage,
    int? totalPages,
  }) {
    return NotificationListState(
      notifications: notifications ?? this.notifications,
      isLoading: isLoading ?? this.isLoading,
      isLoadingMore: isLoadingMore ?? this.isLoadingMore,
      error: error,
      filter: filter ?? this.filter,
      currentPage: currentPage ?? this.currentPage,
      totalPages: totalPages ?? this.totalPages,
    );
  }
}

final notificationListProvider =
    StateNotifierProvider<NotificationListNotifier, NotificationListState>(
        (ref) {
  return NotificationListNotifier(NotificationRepository(), ref);
});

class NotificationListNotifier extends StateNotifier<NotificationListState> {
  final NotificationRepository _repo;
  final Ref _ref;

  NotificationListNotifier(this._repo, this._ref)
      : super(const NotificationListState());

  Future<void> loadNotifications({String filter = 'all'}) async {
    state = state.copyWith(isLoading: true, error: null, filter: filter);
    try {
      final response =
          await _repo.getNotifications(filter: filter, page: 1, limit: 20);
      state = state.copyWith(
        notifications: response.notifications,
        isLoading: false,
        currentPage: response.currentPage,
        totalPages: response.totalPages,
      );
    } catch (e) {
      state = state.copyWith(isLoading: false, error: e.toString());
    }
  }

  Future<void> loadMore() async {
    if (state.isLoadingMore || state.currentPage >= state.totalPages) return;

    state = state.copyWith(isLoadingMore: true);
    try {
      final nextPage = state.currentPage + 1;
      final response = await _repo.getNotifications(
          filter: state.filter, page: nextPage, limit: 20);
      state = state.copyWith(
        notifications: [...state.notifications, ...response.notifications],
        isLoadingMore: false,
        currentPage: response.currentPage,
        totalPages: response.totalPages,
      );
    } catch (_) {
      state = state.copyWith(isLoadingMore: false);
    }
  }

  Future<void> markAsRead(String notificationId) async {
    try {
      await _repo.markAsRead(notificationId);
      state = state.copyWith(
        notifications: state.notifications.map((n) {
          if (n.id == notificationId) return n.copyWith(read: true);
          return n;
        }).toList(),
      );
      _ref.read(unreadCountProvider.notifier).refresh();
    } catch (_) {}
  }

  Future<void> markAllAsRead() async {
    try {
      await _repo.markAllAsRead();
      state = state.copyWith(
        notifications:
            state.notifications.map((n) => n.copyWith(read: true)).toList(),
      );
      _ref.read(unreadCountProvider.notifier).refresh();
    } catch (_) {}
  }
}
