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'; 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 '../../domain/usecase/login_usecase.dart'; // 🔹 Импортируем LoginUseCase import '../event/verify_code_event.dart'; import '../state/verify_code_state.dart'; class VerifyCodeBloc extends Bloc { final VerifyCodeUseCase _verifyCodeUseCase; final LoginUseCase _loginUseCase; // 🔹 Добавляем поле для юзкейса логина Timer? _timer; // 🔹 Обновляем конструктор VerifyCodeBloc(this._verifyCodeUseCase, this._loginUseCase) : 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, error: null, )); }); on((event, emit) async { if (state.secondsLeft == 0 && !state.isSubmitting) { emit(state.copyWith(isSubmitting: true, error: null)); try { final newTempToken = await _loginUseCase.execute("+${state.phoneNumber}"); emit(state.copyWith( isSubmitting: false, tempToken: newTempToken, secondsLeft: 60, code: '', error: null, isBlocked: false, )); _startTimer(); } catch (e) { emit(state.copyWith( isSubmitting: false, error: 'Не удалось повторно отправить код. Попробуйте позже.', )); } } }); on((event, emit) { emit(state.copyWith(secondsLeft: event.secondsLeft)); }); on(_onVerifyCodeSubmitted); } void _startTimer() { _timer?.cancel(); _timer = Timer.periodic(const Duration(seconds: 1), (timer) { final currentSeconds = state.secondsLeft; if (currentSeconds <= 1) { timer.cancel(); add(TimerTicked(0)); } else { add(TimerTicked(currentSeconds - 1)); } }); } Future _onVerifyCodeSubmitted(VerifyCodeSubmitted event, Emitter emit,) async { if (state.isSubmitting || state.code.length != 6 || state.secondsLeft == 0) return; emit(state.copyWith(isSubmitting: true, error: null)); // 🔹 Здесь автоматически подставится обновленный из стейта tempToken final result = await _verifyCodeUseCase.execute(state.code, state.tempToken); final newState = switch (result) { Success() => (() { _timer?.cancel(); return 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() => (() { _timer?.cancel(); return state.copyWith( isSubmitting: false, isBlocked: true, error: 'Вы заблокированы за слишком частые попытки', ); })(), _ => state.copyWith( isSubmitting: false, error: 'Произошла ошибка. Попробуйте позже', ), }, }; emit(newState); } @override Future close() { _timer?.cancel(); return super.close(); } }