import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:physigo/friends/models/challenge_location_request.dart'; import 'package:physigo/services/push_notifications_service.dart'; const userId = "tlmysIvwTBaoZKWqBofx"; const name = "John"; const surname = "Smith"; class ChallengeLocationService { static final _db = FirebaseFirestore.instance; static final _users = _db.collection("Users"); static final _shareLocationRequests = _db.collection("ShareLocationRequests"); static final _friends = _db.collection("Friends"); static Future> getShareChallengeLocationRequests() async { final requests = await _shareLocationRequests.where("user_id", isEqualTo: userId).get(); if (requests.docs.isEmpty) { return []; } final requesterIdLocationId = { for (final request in requests.docs) request.data()['requester_id']: {"requestId": request.id, "locationRef": request.data()['location']} }; final requesters = await _users.where(FieldPath.documentId, whereIn: requesterIdLocationId.keys.toList()).get(); final shareChallengeLocationRequests = await Future.wait(requesters.docs.map((requester) async { final data = requester.data(); final place = (await requesterIdLocationId[requester.id]!["locationRef"].get()).data(); return ChallengeLocationRequest( id: requesterIdLocationId[requester.id]!["requestId"]!, name: data['name'], surname: data['surname'], locationName: place['name'], locationRef: requesterIdLocationId[requester.id]!["locationRef"]!); })); return shareChallengeLocationRequests; } static Future shareChallengeLocation(String friendId) async { await Future.wait([_checkExistingFriendRelation(friendId), _checkExistingChallengeLocationRequest(friendId)]); final user = await _users.doc(userId).get(); final shareLocationRequest = {"user_id": friendId, "requester_id": userId, "location": user['weekly_place']}; await _shareLocationRequests.add(shareLocationRequest); PushNotificationsService.sendChallengeLocationRequestNotification(userId, name, surname); } static Future acceptChallengeLocationRequest(ChallengeLocationRequest request) async { final newLocation = {"weekly_place": request.locationRef}; await _users.doc(userId).update(newLocation); await _shareLocationRequests.doc(request.id).delete(); } static Future refuseChallengeLocationRequest(ChallengeLocationRequest request) async { await _shareLocationRequests.doc(request.id).delete(); } static Future _checkExistingFriendRelation(String friendId) async { if (friendId == userId) { return Future.error("You cannot share a location with yourself"); } var friendRelationByUserId = _friends .where("user_id", isEqualTo: userId) .where("friend_id", isEqualTo: friendId) .where("request_status", isEqualTo: "accepted") .get(); var friendRelationByFriendId = _friends .where("friend_id", isEqualTo: userId) .where("user_id", isEqualTo: friendId) .where("request_status", isEqualTo: "accepted") .get(); final relations = await Future.wait([friendRelationByUserId, friendRelationByFriendId]); if (relations.expand((relation) => relation.docs).isEmpty) { return Future.error("You must be friend to share a location"); } } static Future _checkExistingChallengeLocationRequest(String friendId) async { final requests = await _shareLocationRequests .where("requester_id", isEqualTo: userId) .where("user_id", isEqualTo: friendId) .get(); if (requests.docs.isNotEmpty) { return Future.error("You already shared your location with this person"); } } }