import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:krow/core/application/common/validators/email_validator.dart';

part 'sign_in_event.dart';
part 'sign_in_state.dart';

class SignInBloc extends Bloc<SignInEvent, SignInState> {
  String? code;

  SignInBloc() : super(const SignInState()) {
    on<SwitchObscurePasswordEvent>(_onSwitchObscurePassword);
    on<SignInEventSignIn>(_onSignIn);
    on<ResetPassNextStepEvent>(_onResetPassNextStep);
    on<ResetPassBackEvent>(_onResetPassBack);
    on<SignInEventEmailChanged>(_onEmailChanged);
    on<SignInEventPassChanged>(_onPassChanged);
    on<SignInEventOnResetVerified>(_onResetVerified);
    on<ConfirmNewPassEvent>(_onConfirmNewPass);
  }

  void _onSwitchObscurePassword(SwitchObscurePasswordEvent event, emit) {
    emit(state.copyWith(obscurePassword: !state.obscurePassword));
  }

  void _onSignIn(SignInEventSignIn event, emit) async {
    emit(state.copyWith(inLoading: true));

    var validationResult = EmailValidator.validate(state.email);
    if (validationResult != null) {
      emit(state.copyWith(
          emailValidationError: validationResult, inLoading: false));
      return;
    }

    if(event.password.length<8){
      emit(state.copyWith(
          passValidationError: 'Password must be at least 8 characters long.', inLoading: false));
      return;
    }

    try {
      await FirebaseAuth.instance.signInWithEmailAndPassword(
          email: state.email, password: event.password);

      emit(state.copyWith(authSuccess: true, inLoading: false));
    } catch (e) {
      emit(state.copyWith(
          emailValidationError: 'Failed to sign in.', inLoading: false));
    }
  }

  void _onResetPassNextStep(ResetPassNextStepEvent event, emit) async {
    if (state.resetPassStep == ResetPassStep.email) {
      var validationResult = EmailValidator.validate(state.email);
      if (validationResult != null) {
        emit(state.copyWith(inputValidationError: validationResult));
        return;
      }

      try {
        await FirebaseAuth.instance.sendPasswordResetEmail(email: state.email);
      } catch (e) {
        emit(state.copyWith(
            inputValidationError: 'Failed to send password reset email.'));
        return;
      }
    }

    emit(state.copyWith(
        resetPassStep: ResetPassStep.values[state.resetPassStep.index + 1],
        inputValidationError: '',
        obscurePassword: true));
  }

  void _onResetVerified(SignInEventOnResetVerified event, emit) async {
    var email = await FirebaseAuth.instance.verifyPasswordResetCode(event.code);
    try {
      code = event.code;
      emit(state.copyWith(
          resetPassStep: ResetPassStep.email,
          email: email,
          obscurePassword: true));
      return;
    } catch (e) {
      debugPrint(e.toString());
    }
  }

  void _onConfirmNewPass(ConfirmNewPassEvent event, emit) async {
    if (event.password != event.passwordDuplicate) {
      emit(state.copyWith(inputValidationError: 'Passwords do not match.'));
      return;
    }
    try {
      await FirebaseAuth.instance
          .confirmPasswordReset(code: code!, newPassword: event.password);
      emit(state.copyWith(
          resetPassStep: ResetPassStep.success,
          email: '',
          obscurePassword: true));
    } catch (e) {
      emit(state.copyWith(inputValidationError: 'Failed to reset password.'));
      return;
    }
  }

  void _onResetPassBack(ResetPassBackEvent event, emit) {
    emit(state.copyWith(
        resetPassStep: ResetPassStep.email, email: '', obscurePassword: true));
  }

  void _onEmailChanged(SignInEventEmailChanged event, emit) {
    emit(state.copyWith(email: event.email, inputValidationError: '', emailValidationError: ''));
  }

  void _onPassChanged(SignInEventPassChanged event, emit) {
    emit(state.copyWith(passValidationError: ''));
  }
}
