import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import '../../../../../core/error/failure.dart';
import '../../../../../core/functions/base_finctions.dart';
import '../../../../../core/local_source/local_source.dart';
import '../../../../../injector_container.dart';
import '../../../../../service/notification_service.dart';
import '../../../data/model/auth_verification_request.dart';
import '../../../data/model/fcm_add_request.dart';
import '../../../data/model/login_request.dart';
import '../../../data/model/sign_up_request.dart';
import '../../../domain/usecases/fcm_add_usecase.dart';
import '../../../domain/usecases/login_usecase.dart';
import '../../../domain/usecases/sign_up_usecase.dart';
import '../../../domain/usecases/verify_phone_usecase.dart';
import '../../pages/auth_confirm/argument/auth_confirm_argument.dart';

part 'auth_confirm_event.dart';

part 'auth_confirm_state.dart';

class AuthConfirmBloc extends Bloc<AuthConfirmEvent, AuthConfirmState> {
  AuthConfirmBloc(
    this.signUpUseCase,
    this.verifyPhoneUseCase,
    this.loginUseCase,
    this.fcmAddUseCase,
  ) : super(const InitialState(true)) {
    on<TimerChangedEvent>(_timerChanged);
    on<SmsCodeEnterEvent>(_codeChanged);
    on<ResendCodeEvent>(_resendCode);
    on<OnSubmitEvent>(_onSubmitCode);
  }

  final SignUpUseCase signUpUseCase;
  final VerifyPhoneUseCase verifyPhoneUseCase;
  final LoginUseCase loginUseCase;
  final FcmAddUseCase fcmAddUseCase;

  Future<void> _timerChanged(
    TimerChangedEvent event,
    Emitter<AuthConfirmState> emit,
  ) async {
    emit(InitialState(event.isVisible));
  }

  void _codeChanged(SmsCodeEnterEvent event, Emitter<AuthConfirmState> emit) {
    if (event.code.length == 4) {
      emit(ButtonEnableState(state.isTimerVisible, event.code));
    } else {
      emit(InitialState(state.isTimerVisible));
    }
  }

  Future<void> _resendCode(
    ResendCodeEvent event,
    Emitter<AuthConfirmState> emit,
  ) async {
    add(const TimerChangedEvent(isVisible: true));
    if (event.argument.fromLoginPage) {
      await loginUseCase(
        LoginRequest(
          email: event.argument.mail,
          phone: event.argument.phoneNumber?.replaceAll("+", ""),
          ucode: event.argument.password,
        ),
      );
    } else {
      await signUpUseCase(
        SignUpRequest(
          fullname: event.argument.fullName,
          email: event.argument.mail,
          phoneNumber: event.argument.phoneNumber?.replaceAll("+", ""),
        ),
      );
    }
  }

  Future<void> _onSubmitCode(
    OnSubmitEvent event,
    Emitter<AuthConfirmState> emit,
  ) async {
    emit(LoadingState(state.isTimerVisible));
    final response = await verifyPhoneUseCase(
      AuthVerificationRequest(
        phoneNumber: event.argument?.phoneNumber?.replaceAll("+", ""),
        smsCode: event.code,
        email: event.argument?.mail ?? "",
      ),
    );
    await response.fold(
      (l) {
        if (l is ServerFailure) {
          Functions.showErrorSnackBar(l.message);
        }
        emit(InitialState(state.isTimerVisible));
      },
      (r) async {
        sl<LocalSource>().setHasProfile(true);
        sl<LocalSource>().setAccessToken(r.accessToken ?? "");
        await _addFcmToken();
        emit(SuccessSate(state.isTimerVisible));
      },
    );
  }

  Future<void> _addFcmToken() async {
    final String fcmToken = await NotificationService.getFcmToken();
    await fcmAddUseCase(FcmAddRequest(sfmToken: fcmToken));
  }
}
