import 'dart:convert'; import 'dart:developer'; import 'package:get/get.dart'; import 'package:onufitness/constants/api_endpoints.dart'; import 'package:onufitness/screens/echoboard/models/coach_reviews_response_model.dart'; import 'package:onufitness/services/api_services/base_api_services.dart'; import 'package:onufitness/utils/custom_sneakbar.dart'; class ReviewsController extends GetxController { // Observable variables RxBool isLoading = false.obs; RxBool isLoadingMore = false.obs; RxBool reachedEnd = false.obs; RxString revieweeId = "".obs; RxDouble averageRating = 0.0.obs; RxInt totalReviews = 0.obs; RxList reviews = [].obs; // Pagination variables RxInt currentPage = 1.obs; final int pageSize = 5; // Reset pagination when refreshing the screen void resetPagination() { currentPage.value = 1; reachedEnd.value = false; reviews.clear(); } // Get user reviews with pagination Future getUserReviews() async { if (revieweeId.value.isEmpty) { log("Reviewee ID is empty, skipping API call"); return; } if (currentPage.value == 1) { isLoading(true); } else { isLoadingMore(true); } try { final url = "${ApiUrl.fetchUserReviews}/${revieweeId.value}?PageNumber=${currentPage.value}&PageSize=$pageSize"; final response = await ApiBase.getRequest(extendedURL: url); log("Get Reviews API Response Code: ${response.statusCode}"); if (response.statusCode == 200) { final responseData = CoachReviewsResponseModel.fromJson( jsonDecode(response.body), ); if (responseData.isSuccess == true) { log("Reviews fetched successfully"); // Update total reviews and average rating if (responseData.data != null) { averageRating.value = responseData.data!.userAvgReviewRating ?? 0.0; totalReviews.value = responseData.data!.totalReviews ?? 0; final newReviews = responseData.data!.userReviewRatings ?? []; // If it's the first page, replace the list, otherwise append if (currentPage.value == 1) { reviews.value = newReviews; } else { reviews.addAll(newReviews); } // Check if we've reached the end if (newReviews.length < pageSize) { reachedEnd.value = true; } // Increment page number for next fetch currentPage.value++; } } else { log("Reviews API returned error: ${responseData.message}"); customSnackbar( title: "Error", message: responseData.message ?? "Failed to load reviews", ); } } else { log("Reviews API failed with status: ${response.statusCode}"); customSnackbar(title: "Error", message: "Failed to load reviews"); } } catch (e) { log("Exception in getUserReviews: $e"); customSnackbar(title: "Error", message: "Failed to load reviews"); } finally { isLoading(false); isLoadingMore(false); } } // Load more reviews when scrolling Future loadMoreReviews() async { if (!reachedEnd.value && !isLoadingMore.value) { await getUserReviews(); } } // Submit a new review Future submitReview(int rating, String reviewDescription) async { isLoading(true); bool result = false; try { final url = ApiUrl.createUserReview; final body = { "revieweeID": revieweeId.value, "rating": rating, "reviewDescription": reviewDescription, }; final response = await ApiBase.postRequest(extendedURL: url, body: body); log("Submit Review API Response Code: ${response.statusCode}"); if (response.statusCode == 200 || response.statusCode == 201) { final responseData = jsonDecode(response.body); if (responseData['isSuccess'] == true) { log("Review submitted successfully"); // Refresh reviews resetPagination(); await getUserReviews(); result = true; } else { log("Submit Review API returned error: ${responseData['message']}"); customSnackbar( title: "Error", message: responseData['message'] ?? "Failed to submit review", duration: 1, ); } } else { final responseData = jsonDecode(response.body); log("Submit Review API failed with status: ${response.body}"); customSnackbar( title: "Error", message: responseData['message'] ?? "Failed to submit review", duration: 1, ); } } catch (e) { customSnackbar( title: "Error", message: "Failed to submit review", duration: 1, ); } finally { isLoading(false); } return result; } }