import 'dart:developer'; import 'package:dio/dio.dart'; import 'package:easy_debounce/easy_debounce.dart'; import 'package:eatvio_app/core/utils/toasts.dart'; import 'package:eatvio_app/features/diets/repositories/diet_repository.dart'; import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart'; import 'package:eatvio_app/features/plans/presentation/cubit/about_plan_state.dart'; import 'package:eatvio_app/features/plans/repositories/plan_repository.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:eatvio_app/core/error_reporting/report_from.dart'; class AboutPlanCubit extends Cubit { final PlanRepository planRepository; AboutPlanCubit({required this.planRepository}) : super(AboutPlanState.initial()); Future getPlan({required String slug, int? index}) async { try { final plan = await planRepository.getPlan(slug); if (index != null) { planRepository.emitCommentsStateToFeed(CommentsState(index: index, totalComments: plan.totalComments)); } emit(state.copyWith(planModel: plan, error: null)); } catch (e, stackTrace) { await reportFrom(e, stackTrace, this); log(e.toString(), stackTrace: stackTrace); emit(state.copyWith(error: e.toString(), isLoading: false)); } } Future getPlanWithLoading(String slug) async { try { emit(state.copyWith(isLoading: true)); final plan = await planRepository.getPlan(slug); emit(state.copyWith(planModel: plan, error: null, isLoading: false)); } catch (e, stackTrace) { await reportFrom(e, stackTrace, this); log(e.toString(), stackTrace: stackTrace); emit(state.copyWith(error: e.toString(), isLoading: false)); } } void choseOption(int index) { emit(state.copyWith(chosenOptionIndex: index)); } Future likePlan({required int? index, required String slug}) async { final currentPlan = state.planModel; if (currentPlan == null) return; if (currentPlan.wasLikedByMe) { emit(state.copyWith(planModel: currentPlan.copyWith(wasLikedByMe: false, totalLikes: currentPlan.totalLikes - 1), error: null)); if (index != null) { planRepository.emitLikesStateToFeed(LikesState(wasLikedByMe: false, totalLikes: currentPlan.totalLikes - 1, index: index)); } } else { emit(state.copyWith(planModel: currentPlan.copyWith(wasLikedByMe: true, totalLikes: currentPlan.totalLikes + 1), error: null)); if (index != null) { planRepository.emitLikesStateToFeed(LikesState(wasLikedByMe: true, totalLikes: currentPlan.totalLikes + 1, index: index)); } } EasyDebounce.debounce('like_plan_$slug', const Duration(seconds: 1), () async { try { await planRepository.likePlan(slug); } catch (e, st) { await reportFrom(e, st, this); log(e.toString()); if (index != null) { planRepository.emitLikesStateToFeed(LikesState(wasLikedByMe: currentPlan.wasLikedByMe, totalLikes: currentPlan.totalLikes, index: index)); } emit(state.copyWith(planModel: currentPlan, error: null)); } }); } Future addToFavorite({required String slug, required int? index}) async { final currentPlan = state.planModel; if (currentPlan == null) return; emit(state.copyWith(planModel: currentPlan.copyWith(isFavorite: true))); if (index != null) { planRepository.emitFavoriteStateToFeed(FavoriteState(isFavorite: true, index: index)); } EasyDebounce.debounce('add_or_remove_plan_to_favorites', const Duration(seconds: 1), () async { try { await planRepository.addToFavorite(slug); } catch (e, st) { await reportFrom(e, st, this); log(e.toString()); showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время'); if (index != null) { planRepository.emitFavoriteStateToFeed(FavoriteState(isFavorite: currentPlan.isFavorite, index: index)); } emit(state.copyWith(planModel: currentPlan, error: null)); } }); } Future removeFromFavorite({required String slug, required int? index}) async { final currentPlan = state.planModel; if (currentPlan == null) return; emit(state.copyWith(planModel: currentPlan.copyWith(isFavorite: false))); if (index != null) { planRepository.emitFavoriteStateToFeed(FavoriteState(isFavorite: false, index: index)); } EasyDebounce.debounce('add_or_remove_plan_to_favorites', const Duration(seconds: 1), () async { try { await planRepository.removeFromFavorite(slug); } catch (e, st) { await reportFrom(e, st, this); log(e.toString()); showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время'); if (index != null) { planRepository.emitFavoriteStateToFeed(FavoriteState(isFavorite: currentPlan.isFavorite, index: index)); } emit(state.copyWith(planModel: currentPlan, error: null)); } }); } Future<(ChosenPlanModel?, String?)> chosePlan() async { try { final slug = state.planModel?.slug; final optionIndex = state.chosenOptionIndex; if (slug != null) { final optionName = _getOptionNameFromIndex(optionIndex); final body = {'options_type': optionName}; return (await planRepository.chosePlan(slug, body), null); } } on DioException catch (e, st) { await reportFrom(e, st, this); if (e.response?.statusCode == 400) { return (null, 'hasPlan'); } log(e.toString(), stackTrace: st); } catch (e, st) { await reportFrom(e, st, this); log(e.toString(), stackTrace: st); } return (null, ''); } String _getOptionNameFromIndex(int index) => switch (index) { 1 => 'options2', 2 => 'options3', _ => 'options1', }; }