import 'package:get/get.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import '../../base/base_response_model.dart';
import '../../networking/restful_api_viewmodel.dart';
import '../../preference/data_preference.dart';
import '../../shared/router_gage.dart';
import 'models/category_notify_item_model.dart';
import 'models/notification_detail_model.dart';
import 'models/notification_item_model.dart';
import 'models/notification_list_data_model.dart';
import 'notification_detail_screen.dart';

class NotificationViewModel extends RestfulApiViewModel {
  final RxList<CategoryNotifyItemModel> categories = <CategoryNotifyItemModel>[].obs;
  final RxList<NotificationItemModel> notifications = <NotificationItemModel>[].obs;
  final RxBool isLoading = false.obs;
  final _pageLimit = 10;
  var _notificationIndex = 0;
  void Function(String message)? onShowAlertError;
  var _hasMoreData = true;

  CategoryNotifyItemModel? get selectedCategory =>
      categories.isNotEmpty ? categories.firstWhere((item) => item.isSelected ?? false) : null;
  
  @override
  void onInit() {
    super.onInit();
    _fetchCategories();
  }

  void _fetchCategories() async {
    await callApi<List<CategoryNotifyItemModel>>(
      request: () => client.getNotificationCategories(),
      onSuccess: (data, _) {
        if (data.isNotEmpty) data[0].isSelected = true;
        categories.assignAll(data);
        fetchNotifications(refresh: true);
      },
      onFailure: (msg, _, _) async {
        onShowAlertError?.call(msg);
      },
    );
  }

  void fetchNotifications({bool refresh = false}) async {
    if (isLoading.value) return;
    if (!refresh && !_hasMoreData) { return; }
    if (refresh) {
      _notificationIndex = 0;
    }
    isLoading.value = true;
    String? token = DataPreference.instance.token ?? "";
    final body = {
      "access_token": token,
      "start": _notificationIndex,
      "limit": _pageLimit,
      "noti_group_id": selectedCategory?.id ?? "",
    };
    await callApi<NotificationListDataModel>(
      request: () => client.getNotifications(body),
      onSuccess: (data, _) {
        final items = data.items ?? [];
        if (refresh) {
          notifications.assignAll(items);
        } else {
          notifications.addAll(items);
        }
        _notificationIndex += items.length;
        _hasMoreData = items.length == _pageLimit;
      },
      onFailure: (msg, _, _) async {
        onShowAlertError?.call(msg);
      },
      withLoading: refresh,
      onComplete: () {
        isLoading.value = false;
      },
    );
  }

  void selectCategory(int index) {
    for (var i = 0; i < categories.length; i++) {
      categories[i].isSelected = i == index;
    }
    fetchNotifications(refresh: true);
  }

  void notificationMarkAsSeen() {
    callApi<EmptyCodable>(
      request: () => client.notificationMarkAsSeen(),
      onSuccess: (_, _) => _fetchCategories(),
      onFailure: (msg, _, _) async {
        onShowAlertError?.call(msg);
      },
    );
  }

  void deleteAllNotifications() {
    callApi<EmptyCodable>(
      request: () => client.deleteAllNotifications(),
      onSuccess: (_, _) => _fetchCategories(),
      onFailure: (msg, _, _) async {
        onShowAlertError?.call(msg);
      },
    );
  }

  void handleRemoveNotification(NotificationItemModel item) {
    if (item.notificationId == null) return;
    callApi<EmptyCodable>(
      request: () => client.deleteNotification(item.notificationId ?? ""),
      onSuccess: (_, _) {
        notifications.remove(item);
        if (notifications.length <= _pageLimit) {
          fetchNotifications(refresh: false);
        }
      },
      onFailure: (msg, _, _) async {
        onShowAlertError?.call(msg);
      },
    );
  }

  void handleClickNotification(NotificationItemModel item) {
    callApi<NotificationDetailResponseModel>(
      request: () => client.getNotificationDetail(item.notificationId ?? ""),
      onSuccess: (data, _) {
        final notification = data.notification;
        if (notification == null) return;
        final pushSuccess = notification.directionalScreen?.begin() ?? false;
        if (!pushSuccess) {
          Get.toNamed(notificationDetailScreen, arguments: {'notification': notification, 'notificationId': item.notificationId});
        }
      },
      onFailure: (msg, _, _) async {
        onShowAlertError?.call(msg);
      },
    );
  }
}
