import 'dart:convert';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/configs/constants.dart';
import 'package:mypoint_flutter_app/networking/restful_api_request.dart';
import 'package:mypoint_flutter_app/screen/otp/forgot_pass_otp_repository.dart';
import 'package:mypoint_flutter_app/screen/otp/otp_screen.dart';
import '../../base/base_response_model.dart';
import '../../base/restful_api_viewmodel.dart';
import '../../model/auth/login_token_response_model.dart';
import '../../permission/biometric_manager.dart';
import '../../preference/data_preference.dart';
import '../main_tab_screen/main_tab_screen.dart';

// login_state_enum.dart
enum LoginState { idle, typing, error }

class LoginViewModel extends RestfulApiViewModel {
  final BiometricManager _biometricManager = BiometricManager();

  var loginState = LoginState.idle.obs;
  var isPasswordVisible = false.obs;
  var password = "".obs;
  var biometricType = BiometricTypeEnum.none.obs;

  void Function(String message)? onShowAlertError;
  void Function(String message)? onShowDeviceError;
  void Function(String message)? onShowChangePass;
  void Function(String message)? onShowInvalidAccount;

  @override
  void onInit() {
    super.onInit();
    _initBiometric();
  }

  Future<void> _initBiometric() async {
    final type = await _biometricManager.checkDeviceBiometric();
    biometricType.value = type;
  }

  Future<bool> canUseBiometrics() async {
    return _biometricManager.canCheckBiometrics();
  }

  void onPasswordChanged(String value) {
    password.value = value;
    if (value.isEmpty) {
      loginState.value = LoginState.idle;
    } else {
      loginState.value = LoginState.typing;
    }
  }

  void togglePasswordVisibility() {
    isPasswordVisible.value = !isPasswordVisible.value;
  }

  void onLoginPressed(String phone) {
    if (password.value.isEmpty) return;
    showLoading();
    client.login(phone, password.value).then((value) async {
      hideLoading();
      _handleLoginResponse(value, phone);
    });
  }

  void _getUserProfile() {
    showLoading();
    client.getUserProfile().then((value) async {
      hideLoading();
      final userProfile = value.data;
      if (value.isSuccess && userProfile != null) {
          await DataPreference.instance.saveUserProfile(userProfile);
          Get.to(MainTabScreen());
      } else {
        DataPreference.instance.clearLoginToken();
        final mgs = value.errorMessage ?? Constants.commonError;
        onShowAlertError?.call(mgs);
      }
    });
  }

  void onChangePhonePressed() {
    Get.back();
  }

  void onForgotPassPressed(String phone) {
    showLoading();
    client.otpCreateNew(phone).then((value) {
      hideLoading();
      // TODO: handle error later
      if (value.isSuccess) {
        Get.to(
          OtpScreen(
            repository: ForgotPassOTPRepository(phone, value.data?.resendAfterSecond ?? Constants.otpTtl),
          ),
        );
      }
    });
  }

  Future<void> _handleLoginResponse(BaseResponseModel<LoginTokenResponseModel> response, String phone) async {
    if (response.isSuccess && response.data != null) {
      await DataPreference.instance.saveLoginToken(response.data!);
      _getUserProfile();
      return;
    }
    final errorMsg = response.errorMessage ?? Constants.commonError;
    final errorCode = response.errorCode;

    if (errorCode == ErrorCodes.deviceUndefined) {
      onShowDeviceError?.call(errorMsg);
    } else if (errorCode == ErrorCodes.requiredChangePass) {
      onShowChangePass?.call(errorMsg);
    } else if (errorCode == ErrorCodes.invalidAccount) {
      onShowInvalidAccount?.call(errorMsg);
    } else {
      if (errorCode == ErrorCodes.bioTokenInvalid) {
        DataPreference.instance.clearBioToken(phone);
      }
      onShowAlertError?.call(errorMsg);
    }
  }

  /// Xác thực đăng nhập bằng sinh trắc
  Future<void> onBiometricLoginPressed(String phone) async {
    final canUse = await canUseBiometrics();
    if (!canUse || biometricType.value == BiometricTypeEnum.none) {
      onShowAlertError?.call("Thiết bị không hỗ trợ sinh trắc học");
      return;
    }
    final bioToken = await DataPreference.instance.getBioToken(phone) ?? "";
    if (bioToken.isEmpty) {
      onShowAlertError?.call("Tài khoản này chưa kích hoạt đăng nhập bằng sinh trắc học!\nVui lòng đăng nhập > cài đặt để kích hoạt tính năng");
      return;
    }
    client.loginWithBiometric(phone).then((value) async {
      hideLoading();
      _handleLoginResponse(value, phone);
    });
  }
}
