import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:onufitness/constants/api_endpoints.dart'; import 'package:onufitness/screens/accounts/model/coach_rating_response_model.dart'; import 'package:onufitness/services/api_services/base_api_services.dart'; import 'package:onufitness/utils/custom_sneakbar.dart'; class RatingsReviewsController extends GetxController { var isLoading = false.obs; var coachRatingsData = Rxn(); var currentPage = 1.obs; var pageSize = 10.obs; var hasMoreData = true.obs; var isLoadingMore = false.obs; @override void onInit() { fetchRatingsReviews(isRefresh: true); super.onInit(); scrollController = ScrollController(); scrollController.addListener(_scrollListener); } @override void onClose() { scrollController.dispose(); super.onClose(); } late ScrollController scrollController; void _scrollListener() { if (scrollController.position.pixels == scrollController.position.maxScrollExtent) { if (!isLoadingMore.value && hasMoreData.value) { loadMoreReviews(); } } } Future fetchRatingsReviews({bool isRefresh = false}) async { if (isRefresh) { currentPage.value = 1; hasMoreData.value = true; } isLoading(true); try { var response = await ApiBase.getRequest( extendedURL: "${ApiUrl.getCoachReviewRating}?PageNumber=${currentPage.value}&PageSize=${pageSize.value}", sendHeaders: true, ); log("Response Status Code: ${response.statusCode}"); log("Response Body: ${response.body}"); if (response.statusCode == 200 || response.statusCode == 201) { var responseModel = coachRatingsResponseModelFromJson(response.body); if (responseModel.isSuccess == true) { if (isRefresh || currentPage.value == 1) { coachRatingsData.value = responseModel; } else { // Append new reviews to existing list if (coachRatingsData.value?.data?.userReviewRatings != null) { coachRatingsData.value!.data!.userReviewRatings!.addAll( responseModel.data?.userReviewRatings ?? [], ); coachRatingsData.refresh(); } } // Check if there are more reviews to load int currentReviewsCount = coachRatingsData.value?.data?.userReviewRatings?.length ?? 0; int totalReviews = coachRatingsData.value?.data?.totalReviews ?? 0; hasMoreData.value = currentReviewsCount < totalReviews; } else { log("Failed to fetch reviews : Else 1"); } } else { log("Failed to fetch reviews : Else 2"); } } catch (e) { log("Error fetching ratings: ${e.toString()}"); customSnackbar( title: "Error", message: "Something went wrong while fetching reviews", ); } isLoading(false); } Future loadMoreReviews() async { if (isLoadingMore.value || !hasMoreData.value) return; isLoadingMore(true); currentPage.value++; try { var response = await ApiBase.getRequest( extendedURL: "${ApiUrl.getCoachReviewRating}?PageNumber=${currentPage.value}&PageSize=${pageSize.value}", sendHeaders: true, ); log("Ratting response body :------> ${response.body}"); if (response.statusCode == 200 || response.statusCode == 201) { var responseModel = coachRatingsResponseModelFromJson(response.body); if (responseModel.isSuccess == true && responseModel.data?.userReviewRatings != null) { if (responseModel.data!.userReviewRatings!.isNotEmpty) { coachRatingsData.value!.data!.userReviewRatings!.addAll( responseModel.data!.userReviewRatings!, ); coachRatingsData.refresh(); } else { hasMoreData.value = false; } int currentReviewsCount = coachRatingsData.value?.data?.userReviewRatings?.length ?? 0; int totalReviews = coachRatingsData.value?.data?.totalReviews ?? 0; hasMoreData.value = currentReviewsCount < totalReviews; } else { hasMoreData.value = false; } } else { hasMoreData.value = false; } } catch (e) { log("Error loading more reviews: ${e.toString()}"); hasMoreData.value = false; } isLoadingMore(false); } Future refreshReviews() async { await fetchRatingsReviews(isRefresh: true); } // Get rating percentage for progress bars double getRatingPercentage(int starCount, int totalReviews) { if (totalReviews == 0) { return 0.0; } else { return (starCount / totalReviews) * 100; } } // Get star count by rating int getStarCount(int rating) { switch (rating) { case 5: return coachRatingsData.value?.data?.countOf5Star ?? 0; case 4: return coachRatingsData.value?.data?.countOf4Star ?? 0; case 3: return coachRatingsData.value?.data?.countOf3Star ?? 0; case 2: return coachRatingsData.value?.data?.countOf2Star ?? 0; case 1: return coachRatingsData.value?.data?.countOf1Star ?? 0; default: return 0; } } }