import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:kasy_kit/features/feedbacks/api/entities/feature_vote_entity.dart';

final featureVoteApiProvider = Provider<FeatureVoteApi>(
  (ref) => FeatureVoteApi(
    client: FirebaseFirestore.instance,
  ),
);

class FeatureVoteApi {
  final FirebaseFirestore _client;

  FeatureVoteApi({
    required FirebaseFirestore client,
  }) : _client = client;

  CollectionReference<UserFeatureVoteEntity?> _featureVoteCollection(
          String featureId) =>
      _client
          .collection('feature_requests')
          .doc(featureId)
          .collection('votes')
          .withConverter(
            fromFirestore: (snapshot, _) {
              if (snapshot.exists) {
                return UserFeatureVoteEntity.fromJson(
                    snapshot.id, snapshot.data()!);
              }
              return null;
            },
            toFirestore: (data, _) => data!.toJson(),
          );

  Query<UserFeatureVoteEntity?> get collectionGroup =>
      _client.collectionGroup('votes').withConverter(
            fromFirestore: (snapshot, _) {
              if (snapshot.exists) {
                return UserFeatureVoteEntity.fromJson(
                    snapshot.id, snapshot.data()!);
              }
              return null;
            },
            toFirestore: (data, _) => data!.toJson(),
          );

  Future<List<UserFeatureVoteEntity>> getUserVotes(String userId) async {
    final snapshot =
        await collectionGroup.where('userId', isEqualTo: userId).get();
    return snapshot.docs.map((e) => e.data()!).toList();
  }

  Future<UserFeatureVoteEntity> create(String userId, String featureId) async {
    final result = UserFeatureVoteEntity(
      id: userId,
      userId: userId,
      creationDate: DateTime.now(),
      featureId: featureId,
    );
    final batch = _client.batch();
    batch.set(_featureVoteCollection(featureId).doc(userId), result);
    batch.update(
      _client.collection('feature_requests').doc(featureId),
      {'votes': FieldValue.increment(1), 'last_update_date': FieldValue.serverTimestamp()},
    );
    await batch.commit();
    return result;
  }

  Future<void> delete(String featureId, String voteId) async {
    final batch = _client.batch();
    batch.delete(_featureVoteCollection(featureId).doc(voteId));
    batch.update(
      _client.collection('feature_requests').doc(featureId),
      {'votes': FieldValue.increment(-1), 'last_update_date': FieldValue.serverTimestamp()},
    );
    await batch.commit();
  }
}
