import 'dart:convert'; import 'dart:developer' as developer; import 'package:get/get.dart'; import 'package:onufitness/constants/api_endpoints.dart'; import 'package:onufitness/screens/echoboard/controllers/echoboard_controller.dart'; import 'package:onufitness/screens/echoboard/models/parent_comments_response_model.dart'; import 'package:onufitness/screens/echoboard/models/post_model.dart'; import 'package:onufitness/services/api_services/base_api_services.dart'; import 'package:onufitness/utils/custom_sneakbar.dart'; class LikeCommentController extends GetxController { RxInt commentCurrentPage = 1.obs; final int commentPageSize = 10; final hasMoreComments = true.obs; final isCommentPaginationLoading = false.obs; RxString postId = "".obs; final commentsResponseModel = ParentCommentResponseModel().obs; RxBool isCommentsFetchLoading = false.obs; RxBool isCommentSubmitting = false.obs; final Rx replyingTo = Rx(null); final Rx parentOfReply = Rx(null); final RxSet loadingSubCommentIds = RxSet(); void resetReplyState() { replyingTo.value = null; parentOfReply.value = null; } void startReply(CommentItem comment, CommentItem? parentComment) { replyingTo.value = comment; parentOfReply.value = parentComment; } Future fetchcomments({bool refresh = false}) async { if (refresh) { commentCurrentPage.value = 1; hasMoreComments.value = true; commentsResponseModel.value = ParentCommentResponseModel(); } isCommentPaginationLoading(true); if (refresh) isCommentsFetchLoading(true); try { final response = await ApiBase.getRequest( extendedURL: "${ApiUrl.getParentCommentList}/${postId.value}?pageNumber=${commentCurrentPage.value}&pagesize=$commentPageSize", ); developer.log("Fetch comments status: ${response.statusCode}"); if (response.statusCode == 200 || response.statusCode == 201) { final newData = parentCommentResponseModelFromJson(response.body); if (newData.isSuccess == true && newData.data != null) { if (refresh) { commentsResponseModel.value = newData; } else { final currentItems = commentsResponseModel.value.data?.items ?? []; final newItems = newData.data?.items ?? []; commentsResponseModel.value.data?.items = [ ...currentItems, ...newItems, ]; commentsResponseModel.value.data?.totalCount = newData.data?.totalCount; commentsResponseModel.refresh(); } final fetchedItemsCount = commentsResponseModel.value.data?.items?.length ?? 0; final totalItemsCount = newData.data?.totalCount ?? 0; hasMoreComments.value = fetchedItemsCount < totalItemsCount; if (newData.data?.items?.isNotEmpty == true) { commentCurrentPage.value++; } else { hasMoreComments.value = false; } return true; } else { customSnackbar( title: "Error", message: newData.message ?? "Failed to fetch Comments", duration: 1, ); return false; } } else { customSnackbar( title: "Error", message: "Failed to fetch Comments", duration: 1, ); return false; } } catch (e) { developer.log("Error fetching comments: ${e.toString()}"); customSnackbar( title: "Error", message: "Failed to load comments. Please try again.", duration: 1, ); return false; } finally { isCommentsFetchLoading(false); isCommentPaginationLoading(false); } } Future submitComment({ required String postId, required String commentText, int? parentCommentId, }) async { isCommentSubmitting(true); try { final isReply = parentCommentId != null; final Map requestBody = isReply ? { "postID": postId, "parentCommentID": parentCommentId, "commentText": commentText, } : { "postID": postId, "parentCommentID": 0, "commentText": commentText, }; developer.log("Submitting comment: $requestBody"); final response = await ApiBase.postRequest( extendedURL: ApiUrl.addComment, body: requestBody, ); developer.log("Comment submission status: ${response.body}"); if (response.statusCode == 200 || response.statusCode == 201) { final responseData = jsonDecode(response.body); return responseData['isSuccess'] == true; } return false; } catch (e) { developer.log("Error submitting comment: ${e.toString()}"); return false; } finally { isCommentSubmitting(false); } } Future fetchSubComments(int parentCommentId) async { loadingSubCommentIds.add(parentCommentId); try { final response = await ApiBase.getRequest( extendedURL: "${ApiUrl.getSubCommentList}/$parentCommentId?pageNumber=1&pagesize=1000", ); developer.log("Fetch subcomments status: ${response.statusCode}"); if (response.statusCode == 200 || response.statusCode == 201) { final responseData = jsonDecode(response.body); if (responseData['isSuccess'] == true && responseData['data'] != null) { final items = commentsResponseModel.value.data?.items; if (items != null) { for (int i = 0; i < items.length; i++) { if (items[i].commentId == parentCommentId) { final subComments = List.from( responseData['data']['items'].map( (x) => CommentItem.fromJson(x), ), ); items[i].subComments = subComments; items[i].totalSubCommentCount = responseData['data']['totalCount']; commentsResponseModel.refresh(); return true; } } } } } return false; } catch (e) { developer.log("Error fetching subcomments: ${e.toString()}"); return false; } finally { loadingSubCommentIds.remove(parentCommentId); } } //...................................................................... // Function to submit post reaction //...................................................................... Future submitPostReaction({ required String postId, required int reactionTypeId, bool isDeleteReaction = false, }) async { try { final response = await ApiBase.postRequest( extendedURL: "${ApiUrl.createUpdatePostReaction}?PostID=$postId&ReactionTypeID=$reactionTypeId&IsDeleteReaction=$isDeleteReaction", body: {}, ); developer.log("Reaction submission status: ${response.statusCode}"); developer.log("Reaction API response body : ${response.body}"); if (response.statusCode == 200 || response.statusCode == 201) { updatePostReaction(postId.toString(), reactionTypeId, isDeleteReaction); final responseData = jsonDecode(response.body); if (responseData['isSuccess'] == true) { return true; } else { return false; } } else { return false; } } catch (e) { developer.log("Error submitting reaction: ${e.toString()}"); customSnackbar( title: "Error", message: "Something went wrong. Please try again.", duration: 1, ); return false; } } //...................................................................... //..........update Post Reaction......................................... //...................................................................... void updatePostReaction(String postId, int reactionTypeId, bool isRemove) { final echoBoardController = Get.find(); final int index = echoBoardController.posts.indexWhere( (post) => post.postId.toString() == postId, ); if (index == -1) return; final oldPost = echoBoardController.posts[index]; final currentReactions = oldPost.totalPostReactions ?? 0; final isAlreadyLiked = oldPost.postReactionTypeId != null; int updatedCount = currentReactions; if (isRemove && isAlreadyLiked) { updatedCount = (currentReactions - 1).clamp(0, double.infinity).toInt(); } else if (!isRemove && !isAlreadyLiked) { updatedCount = currentReactions + 1; } final updatedPost = SocialPostItem( postId: oldPost.postId, userId: oldPost.userId, content: oldPost.content, mediaFiles: oldPost.mediaFiles, profilePicture: oldPost.profilePicture, fullName: oldPost.fullName, userTypeName: oldPost.userTypeName, createdAt: oldPost.createdAt, totalPostComments: oldPost.totalPostComments, postReactionTypeId: isRemove ? null : reactionTypeId, totalPostReactions: updatedCount, poll: oldPost.poll, ); echoBoardController.posts[index] = updatedPost; echoBoardController.update(); echoBoardController.posts.refresh(); } }