import 'package:bloc/bloc.dart';
import 'package:dartz/dartz.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart';

import '../../../domain/auth/auth.dart';

part 'set_password_form_event.dart';
part 'set_password_form_state.dart';
part 'set_password_form_bloc.freezed.dart';

@injectable
class SetPasswordFormBloc
    extends Bloc<SetPasswordFormEvent, SetPasswordFormState> {
  final IAuthRepository _repository;
  SetPasswordFormBloc(this._repository)
    : super(SetPasswordFormState.initial()) {
    on<SetPasswordFormEvent>(_onSetPasswordFormEvent);
  }

  Future<void> _onSetPasswordFormEvent(
    SetPasswordFormEvent event,
    Emitter<SetPasswordFormState> emit,
  ) {
    return event.map(
      registrationTokenChanged: (e) async {
        emit(
          state.copyWith(
            registrationToken: e.registrationToken,
            failureOrSetPasswordOption: none(),
          ),
        );
      },
      passwordChanged: (e) async {
        emit(
          state.copyWith(
            password: e.password,
            failureOrSetPasswordOption: none(),
          ),
        );
      },
      confirmPasswordChanged: (e) async {
        emit(
          state.copyWith(
            confirmPassword: e.confirmPassword,
            failureOrSetPasswordOption: none(),
          ),
        );
      },
      submitted: (e) async {
        Either<AuthFailure, Login>? failureOrSetPassword;
        emit(
          state.copyWith(
            isSubmitting: true,
            failureOrSetPasswordOption: none(),
          ),
        );

        final registrationTokenValid = state.registrationToken.isNotEmpty;
        final passwordValid = state.password.isNotEmpty;
        final confirmPasswordValid = state.confirmPassword.isNotEmpty;

        if (registrationTokenValid && passwordValid && confirmPasswordValid) {
          failureOrSetPassword = await _repository.setPassword(
            registrationToken: state.registrationToken,
            password: state.password,
            confirmPassword: state.confirmPassword,
          );

          emit(
            state.copyWith(
              isSubmitting: false,
              failureOrSetPasswordOption: optionOf(failureOrSetPassword),
            ),
          );
        }
        emit(state.copyWith(showErrorMessages: true, isSubmitting: false));
      },
    );
  }
}
