import 'dart:async'; import 'package:be_happy/core/failures.dart'; import 'package:be_happy/core/result.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../domain/usecase/verify_code_usecase.dart'; import '../event/verify_code_event.dart'; import '../state/verify_code_state.dart'; class VerifyCodeBloc extends Bloc { final VerifyCodeUseCase _verifyCodeUseCase; Timer? _timer; VerifyCodeBloc(this._verifyCodeUseCase) : super(VerifyCodeState.initial()) { on((event, emit) { emit(state.copyWith( phoneNumber: event.phoneNumber, tempToken: event.tempToken, secondsLeft: 60, )); _startTimer(); }); on((event, emit) { emit(state.copyWith(code: event.code)); }); on((event, emit) { if (state.secondsLeft == 0) { emit(state.copyWith(secondsLeft: 60)); _startTimer(); } }); on(_onVerifyCodeSubmitted); } void _startTimer() { _timer?.cancel(); _timer = Timer.periodic(const Duration(seconds: 1), (timer) { if (state.secondsLeft <= 1) { timer.cancel(); emit(state.copyWith(secondsLeft: 0)); } else { emit(state.copyWith(secondsLeft: state.secondsLeft - 1)); } }); } Future _onVerifyCodeSubmitted(VerifyCodeSubmitted event, Emitter emit,) async { if (state.isSubmitting || state.code.length != 6) return; emit(state.copyWith(isSubmitting: true, error: null)); final result = await _verifyCodeUseCase.execute(state.code, state.tempToken); final newState = switch (result) { Success() => state.copyWith( isSubmitting: false, isSuccess: true, ), Failure(failure: final f) => switch (f) { AuthFailure(attemptsLeft: final count) => state.copyWith( isSubmitting: false, attemptsLeft: count, error: 'Неверный код. Осталось попыток: $count', ), AuthBlockFailure() => state.copyWith( isSubmitting: false, isBlocked: true, error: 'Вы заблокированы за слишком частые попытки', ), _ => state.copyWith( isSubmitting: false, error: 'Произошла ошибка. Попробуйте позже', ), }, }; emit(newState); } @override Future close() { _timer?.cancel(); return super.close(); } }