//INBOUND EVENT
import 'package:absenkuv3/Repository/DeviceInfo.dart';
import 'package:absenkuv3/Repository/Model/mDeviceInfo.dart';
import 'package:absenkuv3/Repository/Model/mLogin.dart';
import 'package:absenkuv3/Repository/Model/mSplashScreen.dart';
import 'package:absenkuv3/Repository/Service/userApi.dart';
import 'package:absenkuv3/Repository/sharedPreference.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:sn_progress_dialog/sn_progress_dialog.dart';
import 'CustomFunction.dart';
import 'NavigatorBloc.dart';

abstract class AuthEvent {
  String? username;
  String? password;
  late MDeviceinfo mDeviceInfo;
  BuildContext? context;
  GlobalKey<ScaffoldState>? scaffoldKey;
}

class LoginEvent extends AuthEvent {
  LoginEvent(_username, _password, _context, _scaffoldKey) {
    username = _username;
    password = _password;
    context = _context;
    scaffoldKey = _scaffoldKey;
  }
}

class LogoutEvent extends AuthEvent {
  LogoutEvent(_context, _scaffoldKey) {
    context = _context;
    scaffoldKey = _scaffoldKey;
  }
}
class LogoutKlienEvent extends AuthEvent {
  LogoutKlienEvent(_context, _scaffoldKey) {
    context = _context;
    scaffoldKey = _scaffoldKey;
  }
}

class GetUserDataEvent extends AuthEvent {}

class GetUserDataTerkiniEvent extends AuthEvent {
  GetUserDataTerkiniEvent(_context, _scaffoldKey) {
    context = _context;
    scaffoldKey = _scaffoldKey;
  }
}

class GantiPasswordEvent extends AuthEvent {
  String? passwordLama;
  String? passwordBaru;
  String? konfirmasiPasswordBaru;
  GantiPasswordEvent(_passwordLama, _passwordBaru, _konfirmasiPasswordBaru,
      _context, _scaffoldKey) {
    passwordLama = _passwordLama;
    passwordBaru = _passwordBaru;
    konfirmasiPasswordBaru = _konfirmasiPasswordBaru;
    context = _context;
    scaffoldKey = _scaffoldKey;
  }
}
class GantiPasswordKlienEvent extends AuthEvent {
  String? passwordLama;
  String? passwordBaru;
  String? konfirmasiPasswordBaru;
  GantiPasswordKlienEvent(_passwordLama, _passwordBaru, _konfirmasiPasswordBaru,
      _context, _scaffoldKey) {
    passwordLama = _passwordLama;
    passwordBaru = _passwordBaru;
    konfirmasiPasswordBaru = _konfirmasiPasswordBaru;
    context = _context;
    scaffoldKey = _scaffoldKey;
  }
}

class GantiProfilEvent extends AuthEvent {
  String? noTelp;
  GantiProfilEvent(_noTelp, _context, _scaffoldKey) {
    context = _context;
    scaffoldKey = _scaffoldKey;
    noTelp = _noTelp;
  }
}

class UploadFotoProfilEvent extends AuthEvent {
  String imageBase64;
  UploadFotoProfilEvent(this.imageBase64, _context, _scaffoldKey) {
    context = _context;
    scaffoldKey = _scaffoldKey;
  }
}
//

//OUTBOUND STATE
abstract class AuthState {
  LoginRespon? data;
}

class AuthLoginSuccess extends AuthState {
  AuthLoginSuccess(AuthEvent event, LoginRespon _data) {
    data = _data;
    if (data!.dataLogin!.klien!) {
      BlocProvider.of<NavigatorBloc>(event.context!)
        .add(NavigateRemoveToDashboardKlien(event.context));
    }else{
    BlocProvider.of<NavigatorBloc>(event.context!)
        .add(NavigateRemoveToDashboard(event.context));
    }
  }
}

class AuthLogoutSuccess extends AuthState {
  AuthLogoutSuccess(AuthEvent event) {
    // ProgressDialogDelayed.hide(event.context);
    BlocProvider.of<NavigatorBloc>(event.context!)
        .add(NavigateRemoveToLogin(event.context));
  }
}

class AuthError extends AuthState {
  AuthError(AuthEvent event, String? message) {
    showSnackBarDelayed(event.scaffoldKey, message, event.context);
  }
}

class GantiPasswordSuccess extends AuthState {
  GantiPasswordSuccess(AuthEvent event, BasicRespon data) {
    showSnackBarDelayed(event.scaffoldKey, data.message, event.context);
    Future.delayed(Duration(milliseconds: 1500)).then((value) {
      BlocProvider.of<NavigatorBloc>(event.context!)
          .add(NavigatePop(event.context));
    });
  }
}

class GantiProfilSuccess extends AuthState {
  GantiProfilSuccess(AuthEvent event, BasicRespon data) {
    showSnackBarDelayed(event.scaffoldKey, data.message, event.context);
    Future.delayed(Duration(milliseconds: 1500)).then((value) {
      BlocProvider.of<AuthBloc>(event.context!)
          .add(GetUserDataTerkiniEvent(event.context, event.scaffoldKey));
      BlocProvider.of<NavigatorBloc>(event.context!)
          .add(NavigatePop(event.context));
    });
  }
}

class UploadFotoProfilSuccess extends AuthState {
  UploadFotoProfilSuccess(AuthEvent event, BasicRespon data) {
    showSnackBarDelayed(event.scaffoldKey, data.message, event.context);
    BlocProvider.of<AuthBloc>(event.context!)
        .add(GetUserDataTerkiniEvent(event.context, event.scaffoldKey));
  }
}

class AuthBloc extends Bloc<AuthEvent, LoginRespon> {
  AuthBloc(LoginRespon initialState) : super(initialState);

  @override
  Stream<LoginRespon> mapEventToState(AuthEvent event) async* {
    if (event is LoginEvent) {
      ProgressDialog pd = ProgressDialog(context: event.context);
      ProgressDialogDelayed.show(pd, isDismissible: false);
      event.mDeviceInfo = await DeviceInfo().getDeviceInfo();
      LoginRespon data = await UserApi().login(event);
      ProgressDialogDelayed.hide(pd);
      if (data.success!) {
        await sharedPreferences().setUserData(data);
        await sharedPreferences().setBahasa(data.dataLogin!.bahasa!);
        AuthLoginSuccess(event, data);
      } else
        AuthError(event, data.message);
      // print("LOGIN ${data.message}");
      yield data;
    } else if (event is LogoutEvent) {
      ProgressDialog pd = ProgressDialog(context: event.context);
      ProgressDialogDelayed.show(pd, isDismissible: false);
      BasicRespon data = await UserApi().logout();
      ProgressDialogDelayed.hide(pd);
      if (data.success!) {
        await sharedPreferences().remove('user');
        AuthLogoutSuccess(event);
      } else {
        AuthError(event, data.message);
      }
    } else if (event is LogoutKlienEvent) {
      // ProgressDialog pd = ProgressDialog(context: event.context);
      // ProgressDialogDelayed.show(pd, isDismissible: false);
      // BasicRespon data = await UserApi().logout();
      // ProgressDialogDelayed.hide(pd);
      // if (data.success!) {
        await sharedPreferences().remove('user');
        AuthLogoutSuccess(event);
      // } else {
      //   AuthError(event, data.message);
      // }
    } else if (event is GetUserDataEvent) {
      LoginRespon? data = await sharedPreferences().getUserData();
      yield data;
    } 
    else if (event is GantiPasswordEvent) {
      if (event.passwordBaru != event.konfirmasiPasswordBaru)
        AuthError(
            event, "Password baru dengan konfirmasi password baru berbeda");
      else if (event.passwordLama == '' ||
          event.passwordBaru == '' ||
          event.konfirmasiPasswordBaru == '') {
        AuthError(event, "Password harus diisi");
      } else {
        ProgressDialog pd = ProgressDialog(context: event.context);
        ProgressDialogDelayed.show(pd, isDismissible: false);
        BasicRespon data = await UserApi()
            .changePassword(event.passwordLama, event.passwordBaru);
        ProgressDialogDelayed.hide(pd);
        if (data.success!)
          GantiPasswordSuccess(event, data);
        else
          AuthError(event, data.message);
      }
    }else if (event is GantiPasswordKlienEvent) {
      if (event.passwordBaru != event.konfirmasiPasswordBaru)
        AuthError(
            event, "Password baru dengan konfirmasi password baru berbeda");
      else if (event.passwordLama == '' ||
          event.passwordBaru == '' ||
          event.konfirmasiPasswordBaru == '') {
        AuthError(event, "Password harus diisi");
      } else {
        ProgressDialog pd = ProgressDialog(context: event.context);
        ProgressDialogDelayed.show(pd, isDismissible: false);
        BasicRespon data = await UserApi()
            .changePasswordKlien(event.passwordLama, event.passwordBaru);
        ProgressDialogDelayed.hide(pd);
        if (data.success!)
          GantiPasswordSuccess(event, data);
        else
          AuthError(event, data.message);
      }
    } else if (event is GantiProfilEvent) {
      ProgressDialog pd = ProgressDialog(context: event.context);
      ProgressDialogDelayed.show(pd, isDismissible: false);
      BasicRespon data = await UserApi().ubahProfil(event.noTelp);
      ProgressDialogDelayed.hide(pd);
      if (data.success!)
        GantiProfilSuccess(event, data);
      else
        AuthError(event, data.message);
    } else if (event is GetUserDataTerkiniEvent) {
      LoginRespon data = await UserApi().getUserDataTerkini();
      if (data.success!) {
        await sharedPreferences().setUserData(data);
        yield data;
      } else {
        await sharedPreferences().remove('user');
        AuthLogoutSuccess(event);
      }
    } else if (event is UploadFotoProfilEvent) {
      ProgressDialog pd = ProgressDialog(context: event.context);
      ProgressDialogDelayed.show(pd, isDismissible: false);
      BasicRespon data = await UserApi().uploadFotoProfil(event.imageBase64);
      ProgressDialogDelayed.hide(pd);
      if (data.success!)
        UploadFotoProfilSuccess(event, data);
      else
        AuthError(event, data.message);
    }
  }
}
