import ' dart:convert ' ;
import ' package:easy_localization/easy_localization.dart ' ;
import ' package:flutter/foundation.dart ' ;
import ' package:flutter/material.dart ' ;
import ' package:flutter/services.dart ' ;
import ' package:hmg_nurses/classes/consts.dart ' ;
import ' package:hmg_nurses/classes/enums.dart ' ;
import ' package:hmg_nurses/classes/utils.dart ' ;
import ' package:hmg_nurses/config/routes.dart ' ;
import ' package:hmg_nurses/generated/locale_keys.g.dart ' ;
import ' package:hmg_nurses/main.dart ' ;
import ' package:hmg_nurses/model/base/generic_response_model.dart ' ;
import ' package:hmg_nurses/model/base/generic_response_model2.dart ' ;
import ' package:hmg_nurses/model/login/imei_details_model.dart ' ;
import ' package:hmg_nurses/model/login/member_login_model.dart ' ;
import ' package:hmg_nurses/model/login/project_info_model.dart ' ;
import ' package:hmg_nurses/provider/base_vm.dart ' ;
import ' package:hmg_nurses/services/api_repo/login_api_repo.dart ' ;
import ' package:hmg_nurses/widgets/dialogs/otp_dialog.dart ' ;
import ' package:http/http.dart ' ;
import ' package:injector/injector.dart ' ;
import ' package:local_auth/auth_strings.dart ' ;
import ' package:local_auth/local_auth.dart ' ;
class LoginProviderModel extends BaseViewModel {
//UI variables
late LocalAuthentication auth ;
late bool isFaceBioAvailable , isFingerBioAvailable ;
late List < BiometricType > _availableBiometrics ;
//API's variables
late List < ProjectInfoModel > assignedBranches ;
final ILoginApiRepo _loginApiRepo = Injector . appInstance . get < ILoginApiRepo > ( ) ;
LoginProviderModel ( ) {
setOnlyState ( ViewState . hide ) ;
checkBiosAvailblity ( ) ;
}
checkBiosAvailblity ( ) async {
auth = LocalAuthentication ( ) ;
await _getAvailableBiometrics ( ) ;
isFaceBioAvailable = checkBiometricIsAvailable ( BiometricType . face ) ;
isFingerBioAvailable = checkBiometricIsAvailable ( BiometricType . fingerprint ) ;
}
/// check specific biometric if it available or not
bool checkBiometricIsAvailable ( BiometricType biometricType ) {
bool isAvailable = false ;
for ( int i = 0 ; i < _availableBiometrics . length ; i + + ) {
if ( biometricType = = _availableBiometrics [ i ] ) {
isAvailable = true ;
break ;
}
}
return isAvailable ;
}
/// get all available biometric on the device for local Auth service
Future < void > _getAvailableBiometrics ( ) async {
try {
_availableBiometrics = await auth . getAvailableBiometrics ( ) ;
print ( _availableBiometrics ) ;
} on PlatformException catch ( e ) {
// AppToast.showErrorToast(message: e.message);
print ( " _getAvailableBiometrics " ) ;
print ( e ) ;
}
}
Future < bool > loginWithFaceIDAndBiometrics ( ) async {
IOSAuthMessages iosStrings =
const IOSAuthMessages ( cancelButton: ' cancel ' , goToSettingsButton: ' settings ' , goToSettingsDescription: ' Please set up your Touch ID. ' , lockOut: ' Please re-enable your Touch ID ' ) ;
bool authenticated = false ;
try {
authenticated = await auth . authenticate ( localizedReason: ' Scan your fingerprint to authenticate ' , useErrorDialogs: true , stickyAuth: true , biometricOnly: true , iOSAuthStrings: iosStrings ) ;
} on PlatformException catch ( e ) {
print ( e ) ;
Utils . showToast ( " Please enable your Touch or Face ID " ) ;
}
return authenticated ;
}
int getLoginMethodId ( AuthMethodTypes authMethodTypes ) {
switch ( authMethodTypes ) {
case AuthMethodTypes . sms:
return 1 ;
case AuthMethodTypes . whatsApp:
return 2 ;
case AuthMethodTypes . fingerPrint:
return 3 ;
case AuthMethodTypes . faceID:
return 4 ;
default :
return 1 ;
}
}
String getType ( type ) {
switch ( type ) {
case 1 :
return LocaleKeys . sms . tr ( ) ;
case 3 :
return LocaleKeys . fingerPrint . tr ( ) ;
case 4 :
return LocaleKeys . face . tr ( ) ;
case 2 :
return LocaleKeys . whatsapp . tr ( ) ;
default :
return LocaleKeys . sms . tr ( ) ;
}
}
// LoginType getDirectLoginType(type) {
// switch (type) {
// case 1:
// return LoginType.DIRECT_LOGIN;
// case 3:
// return LocaleKeys.fingerPrint.tr();
// case 4:
// return LocaleKeys.face.tr();
// case 2:
// return LocaleKeys.whatsapp.tr();
// default:
// return LocaleKeys.sms.tr();
// }
// }
//API Calls
checkLastSession ( ) async {
try {
Utils . showLoading ( ) ;
List < GetIMEIDetailsModel > deviceInfo = await _loginApiRepo . getDeviceInfoByIMEI ( ) ;
if ( deviceInfo . isNotEmpty ) getSession ( deviceInfo . first ) ;
Utils . showToast ( deviceInfo . length . toString ( ) ) ;
Utils . hideLoading ( ) ;
} catch ( e ) {
Utils . hideLoading ( ) ;
}
}
getAssignedBranches ( String userId ) async {
setState ( ViewState . busy ) ;
assignedBranches = await _loginApiRepo . getProjectInfo ( userId ) ;
print ( assignedBranches . length ) ;
setState ( ViewState . idle ) ;
}
Future < bool > performLogin ( String userID , String password , int branchId ) async {
try {
Utils . showLoading ( ) ;
MemberLoginModel memberLogin = await _loginApiRepo . memberLogin ( userID , password , branchId ) ;
// Utils.showToast(deviceInfo.length.toString());
appState . setMemberBeforeLogin = memberLogin ;
appState . projectID = branchId ;
appState . logInTokenID = memberLogin . logInTokenId ;
appState . lastLoginTyp = - 1 ;
Utils . hideLoading ( ) ;
Navigator . pushReplacementNamed ( navigatorKey . currentContext ! , AppRoutes . loginMethodsPage , arguments: LoginType . FROM_LOGIN ) ;
return true ;
} catch ( e ) {
Utils . hideLoading ( ) ;
Utils . handleException ( e , navigatorKey . currentContext ! , ( msg ) {
Utils . confirmDialog ( navigatorKey . currentContext ! , msg ) ;
} ) ;
return false ;
}
}
Future < GenericResponseModel ? > sendActivationCode ( MemberLoginModel memberLoginModel , int facilityID , int sendOtpType , LoginType loginType , { bool isNeedBinding = true } ) async {
try {
Utils . showLoading ( isNeedBinding: isNeedBinding ) ;
GenericResponseModel memberLogin ;
if ( loginType = = LoginType . FROM_LOGIN ) {
memberLogin = await _loginApiRepo . sendActivationCode ( memberLoginModel , facilityID , sendOtpType ) ;
appState . logInTokenID = memberLogin . logInTokenId . toString ( ) ;
Utils . hideLoading ( ) ;
startSMSService ( sendOtpType , false ) ;
} else {
if ( loginType = = LoginType . SILENT_LOGIN ) {
memberLogin = await _loginApiRepo . sendActivationCodeForSlientLogin ( memberLoginModel , facilityID , sendOtpType ) ;
appState . logInTokenID = memberLogin . logInTokenId . toString ( ) ;
checkActivationCode ( " 0000 " , sendOtpType , true ) ;
} else {
memberLogin = await _loginApiRepo . sendActivationCodeForSlientLogin ( memberLoginModel , facilityID , sendOtpType ) ;
appState . logInTokenID = memberLogin . logInTokenId . toString ( ) ;
Utils . hideLoading ( ) ;
startSMSService ( sendOtpType , true ) ;
}
}
return memberLogin ;
} catch ( e ) {
Utils . hideLoading ( ) ;
Utils . handleException ( e , navigatorKey . currentContext ! , ( msg ) {
Utils . confirmDialog ( navigatorKey . currentContext ! , msg ) ;
} ) ;
}
return null ;
}
Future < GenericResponseModel ? > checkActivationCode ( String activationCode , int sendOtpType , bool isFromSilentLogin ) async {
try {
if ( ! isFromSilentLogin ) Utils . showLoading ( ) ;
GenericResponseModel memberLogin = await _loginApiRepo . checkActivationCode ( activationCode , sendOtpType , isFromSilentLogin ) ;
Utils . hideLoading ( ) ;
setSession ( memberLogin ) ;
Navigator . pushReplacementNamed ( navigatorKey . currentContext ! , AppRoutes . dashboard ) ;
return memberLogin ;
} catch ( e ) {
Utils . hideLoading ( ) ;
Utils . handleException ( e , navigatorKey . currentContext ! , ( msg ) {
Utils . confirmDialog ( navigatorKey . currentContext ! , msg ) ;
} ) ;
}
return null ;
}
startSMSService ( int sendOtpType , bool isFromSilentLogin ) {
OtpDialog (
type: sendOtpType ,
mobileNo: appState . memberBeforeLogin ! . mobileNumber ,
onSuccess: ( String otpCode , TextEditingController pinPut ) {
Navigator . pop ( navigatorKey . currentContext ! ) ;
Utils . showLoading ( ) ;
checkActivationCode ( otpCode , sendOtpType , isFromSilentLogin ) ;
Utils . hideLoading ( ) ;
} ,
onFailure: ( ) = > Navigator . pop ( navigatorKey . currentContext ! ) ,
onResendCode: ( ) { } ,
) . displayDialog ( navigatorKey . currentContext ! ) ;
}
setSession ( GenericResponseModel response ) {
appState . vidaAuthTokenID = response . vidaAuthTokenId ;
appState . vidaRefreshTokenID = response . vidaRefreshTokenId ;
appState . authenticationTokenID = response . authenticationTokenId ;
appState . listDoctorsClinic = response . listDoctorsClinic ;
appState . projectID = response . listDoctorsClinic ! . first . projectId ! ;
appState . clinicId = response . listDoctorsClinic ! . first . clinicId ! ;
MemberLoginModel . saveToPrefs ( jsonEncode ( appState . memberBeforeLogin ! . toJson ( ) ) ) ;
Utils . saveIntFromPrefs ( SharedPrefsConsts . username , appState . doctorUserId ? ? 0 ) ;
Utils . saveStringFromPrefs ( SharedPrefsConsts . password , appState . password ? ? " " ) ;
Utils . saveStringFromPrefs ( SharedPrefsConsts . logInTokenID , appState . logInTokenID ? ? " " ) ;
Utils . saveStringFromPrefs ( SharedPrefsConsts . vidaAuthTokenID , appState . vidaAuthTokenID ? ? " " ) ;
Utils . saveStringFromPrefs ( SharedPrefsConsts . vidaRefreshTokenID , appState . vidaRefreshTokenID ? ? " " ) ;
Utils . saveStringFromPrefs ( SharedPrefsConsts . authenticationTokenID , appState . authenticationTokenID ? ? " " ) ;
Utils . saveIntFromPrefs ( SharedPrefsConsts . projectID , appState . projectID ) ;
Utils . saveIntFromPrefs ( SharedPrefsConsts . clinicId , appState . clinicId ) ;
Utils . saveStringFromPrefs ( SharedPrefsConsts . lastLoginDate , Utils . getMonthNamedFormat ( DateTime . now ( ) ) ) ;
}
getSession ( GetIMEIDetailsModel model ) async {
int doctorUserId = await Utils . getIntFromPrefs ( SharedPrefsConsts . username ) ;
if ( model . doctorID = = doctorUserId ) {
String password = await Utils . getStringFromPrefs ( SharedPrefsConsts . password ) ;
String logInTokenID = await Utils . getStringFromPrefs ( SharedPrefsConsts . logInTokenID ) ;
String authenticationTokenID = await Utils . getStringFromPrefs ( SharedPrefsConsts . authenticationTokenID ) ;
int clinicId = await Utils . getIntFromPrefs ( SharedPrefsConsts . clinicId ) ;
String lastLoginDate = await Utils . getStringFromPrefs ( SharedPrefsConsts . lastLoginDate ) ;
appState . setMemberBeforeLogin = await MemberLoginModel . getFromPrefs ( ) ;
appState . lastLoginTyp = - 1 ;
appState . doctorUserId = doctorUserId ;
appState . password = password ;
appState . logInTokenID = logInTokenID ;
appState . vidaAuthTokenID = model . vidaAuthTokenID ;
appState . vidaRefreshTokenID = model . vidaRefreshTokenID ;
appState . authenticationTokenID = authenticationTokenID ;
appState . projectID = model . projectID ? ? 0 ;
appState . clinicId = clinicId ;
appState . lastLoginImeiDate = model ;
appState . lastLoginDate = lastLoginDate ;
Navigator . pushReplacementNamed ( navigatorKey . currentContext ! , AppRoutes . loginMethodsPage , arguments: LoginType . SILENT_LOGIN ) ;
}
}
}