import 'package:didvan/config/design_config.dart';
import 'package:didvan/main.dart';
import 'package:didvan/models/comment/comment.dart';
import 'package:didvan/models/comment/feedback.dart';
import 'package:didvan/models/comment/reply.dart';
import 'package:didvan/models/comment/user.dart';
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/view/alert_data.dart';
import 'package:didvan/providers/core.dart';
import 'package:didvan/providers/user.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
import 'package:didvan/utils/action_sheet.dart';
import 'package:provider/provider.dart';

class CommentsState extends CoreProvier {
  String text = '';
  int? commentId;
  UserOverview? replyingTo;
  bool showReplyBox = false;
  late void Function(int count) onCommentsChanged;
  int _count = 0;
  late String type;

  final List<CommentData> comments = [];
  final Map<int, MapEntry<bool, bool>> _feedbackQueue = {};

  int itemId = 0;

  Future<void> getComments() async {
    final service = RequestService(
      RequestHelper.comments(itemId, type),
    );
    await service.httpGet();
    if (service.isSuccess) {
      comments.clear();
      final messages = service.result['comments'];
      for (var i = 0; i < messages.length; i++) {
        comments.add(CommentData.fromJson(messages[i]));
        _count++;
        for (var j = 0; j < messages[i]['replies'].length; j++) {
          _count++;
        }
      }
      appState = AppState.idle;
      return;
    }
    appState = AppState.failed;
  }

  Future<void> feedback({
    required int id,
    required bool like,
    required bool dislike,
    required int likeCount,
    required int dislikeCount,
    int? replyId,
  }) async {
    _feedbackQueue.addAll({id: MapEntry(like, dislike)});
    dynamic comment;
    if (replyId == null) {
      comment = comments.firstWhere((comment) => comment.id == id);
    } else {
      comment = comments
          .firstWhere((comment) => comment.id == id)
          .replies
          .firstWhere((element) => element.id == replyId);
    }

    if (comment != null) {
      comment.feedback.like = likeCount;
      comment.feedback.dislike = dislikeCount;
      comment.disliked = dislike;
      comment.liked = like;
    }
    Future.delayed(const Duration(milliseconds: 500), () async {
      if (!_feedbackQueue.containsKey(id)) return;
      final service = RequestService(
        RequestHelper.feedback(itemId, id, type),
        body: {
          'like': _feedbackQueue[id]!.key,
          'dislike': _feedbackQueue[id]!.value,
        },
      );
      await service.put();
      _feedbackQueue.remove(id);
    });
  }

  Future<void> addComment() async {
    final user = DesignConfig.context!.read<UserProvider>().user;
    if (replyingTo != null) {
      comments.firstWhere((comment) => comment.id == commentId).replies.add(
            Reply(
              id: 0,
              text: text,
              createdAt: DateTime.now().toString(),
              liked: false,
              disliked: false,
              feedback: FeedbackData(like: 0, dislike: 0),
              toUser: replyingTo!,
              user: UserOverview(
                id: user.id,
                fullName: user.fullName,
                photo: user.photo,
              ),
              status: 2,
            ),
          );
    } else {
      comments.insert(
        0,
        CommentData(
          id: 0,
          text: text,
          createdAt: DateTime.now().toString(),
          liked: false,
          disliked: false,
          feedback: FeedbackData(like: 0, dislike: 0),
          user: UserOverview(
            id: user.id,
            fullName: user.fullName,
            photo: user.photo,
          ),
          replies: [],
          status: 2,
        ),
      );
    }

    final body = {};

    if (commentId != null) {
      body.addAll({'commentId': commentId});
    }
    if (replyingTo != null) {
      body.addAll({'replyUserId': replyingTo!.id});
    }
    body.addAll({'status': 2});

    showReplyBox = false;
    update();
    body.addAll({'text': text});
    final service = RequestService(
      RequestHelper.addComment(itemId, type),
      body: body,
    );

    await service.post();
    if (service.isSuccess) {
      if (replyingTo != null) {
        comments
            .firstWhere((comment) => comment.id == commentId)
            .replies
            .firstWhere((reply) => reply.id == 0)
            .id = service.result['comment']['id'];
      } else {
        comments.firstWhere((comment) => comment.id == 0).id =
            service.result['comment']['id'];
      }
      commentId = null;
      replyingTo = null;
    }
  }

  void reportComment(int id) {
    final service = RequestService(RequestHelper.reportComment(id));
    service.post();
    ActionSheetUtils(navigatorKey.currentContext!).showAlert(
      AlertData(
        message: 'گزارش شما با موفقیت ثبت شد و به زودی بررسی میگردد.',
        aLertType: ALertType.success,
      ),
    );
  }

  void deleteComment(int id, int status, int? rootId) async {
    final service = RequestService(RequestHelper.deleteComment(id));
    service.delete();
    if (rootId == null) {
      final comment = comments.firstWhere((element) => element.id == id);
      if (comment.replies.isNotEmpty) {
        _count = 0;
        await getComments();
        onCommentsChanged(_count);
      } else {
        comments.remove(comment);

        if (status != 2) {
          _count--;
          onCommentsChanged(_count);
        }
      }
    } else {
      comments
          .firstWhere((element) => element.id == rootId)
          .replies
          .removeWhere((element) => element.id == id);

      if (status != 2) {
        _count--;
        onCommentsChanged(_count);
      }
    }

    notifyListeners();
  }
}
