import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:formz/formz.dart'; import 'package:equatable/equatable.dart'; import '../../../../core/api/api_exception.dart'; import '../../../../core/form_inputs/form_inputs.dart'; import '../../data/auth_repository.dart'; import '../../data/models/signup_request.dart'; import '../../data/models/auth_response.dart'; class RegisterState extends Equatable { final Username username; final Email email; final Password password; final VerificationCode verificationCode; final FormzSubmissionStatus status; final String? errorMessage; final String? pendingEmail; final bool codeSent; final bool isSending; const RegisterState({ this.username = const Username.pure(), this.email = const Email.pure(), this.password = const Password.pure(), this.verificationCode = const VerificationCode.pure(), this.status = FormzSubmissionStatus.initial, this.errorMessage, this.pendingEmail, this.codeSent = false, this.isSending = false, }); bool get isStep1Valid => username.isValid && email.isValid && password.isValid; bool get isStep2Valid => verificationCode.isValid; RegisterState copyWith({ Username? username, Email? email, Password? password, VerificationCode? verificationCode, FormzSubmissionStatus? status, String? errorMessage, String? pendingEmail, bool? codeSent, bool? isSending, }) { return RegisterState( username: username ?? this.username, email: email ?? this.email, password: password ?? this.password, verificationCode: verificationCode ?? this.verificationCode, status: status ?? this.status, errorMessage: errorMessage, pendingEmail: pendingEmail ?? this.pendingEmail, codeSent: codeSent ?? this.codeSent, isSending: isSending ?? this.isSending, ); } @override List get props => [ username, email, password, verificationCode, status, errorMessage, pendingEmail, codeSent, isSending, ]; } class RegisterCubit extends Cubit { final AuthRepository _repository; RegisterCubit(this._repository) : super(const RegisterState()); void usernameChanged(String value) { emit(state.copyWith(username: Username.dirty(value))); } void emailChanged(String value) { emit(state.copyWith(email: Email.dirty(value))); } void passwordChanged(String value) { emit(state.copyWith(password: Password.dirty(value))); } void verificationCodeChanged(String value) { emit(state.copyWith(verificationCode: VerificationCode.dirty(value))); } Future submitStep1() async { if (!state.isStep1Valid) return false; emit(state.copyWith(status: FormzSubmissionStatus.inProgress)); try { final response = await _repository.signupStart( SignupStartRequest( username: state.username.value, email: state.email.value, password: state.password.value, ), ); emit( state.copyWith( status: FormzSubmissionStatus.success, pendingEmail: response.email, codeSent: true, ), ); return true; } catch (e) { final message = e is ApiException ? e.message : e.toString(); emit( state.copyWith( status: FormzSubmissionStatus.failure, errorMessage: message, ), ); return false; } } Future submitStep2() async { if (!state.isStep2Valid || state.pendingEmail == null) return null; emit(state.copyWith(status: FormzSubmissionStatus.inProgress)); try { final response = await _repository.signupVerify( SignupVerifyRequest( email: state.pendingEmail!, token: state.verificationCode.value, ), ); emit(state.copyWith(status: FormzSubmissionStatus.success)); return response; } catch (e) { final message = e is ApiException ? e.message : e.toString(); emit( state.copyWith( status: FormzSubmissionStatus.failure, errorMessage: message, ), ); return null; } } Future resendCode() async { if (state.pendingEmail == null) return; try { await _repository.signupResend( SignupResendRequest(email: state.pendingEmail!), ); emit(state.copyWith(codeSent: true)); } catch (e) { final message = e is ApiException ? e.message : e.toString(); emit(state.copyWith(errorMessage: message)); } } Future sendCodeSilently() async { if (!state.isStep1Valid) return; emit(state.copyWith(isSending: true)); try { final response = await _repository.signupStart( SignupStartRequest( username: state.username.value, email: state.email.value, password: state.password.value, ), ); emit( state.copyWith( isSending: false, pendingEmail: response.email, codeSent: true, errorMessage: null, ), ); } catch (e) { final message = e is ApiException ? e.message : '验证码发送失败,请重试'; emit(state.copyWith(isSending: false, errorMessage: message)); } } }