import 'dart:convert';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/configs/constants.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_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 'package:mypoint_flutter_app/shared/router_gage.dart';
import '../../base/base_response_model.dart';
import '../../networking/restful_api_viewmodel.dart';
import '../../model/auth/login_token_response_model.dart';
import '../../permission/biometric_manager.dart';
import '../../preference/data_preference.dart';
import '../../firebase/push_token_service.dart';
import '../main_tab_screen/main_tab_screen.dart';

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

class LoginViewModel extends RestfulApiViewModel {
  var loginState = LoginState.idle.obs;
  var isPasswordVisible = false.obs;
  var password = "".obs;
  var isSupportedBiometric = false.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();
    freshBiometric();
  }

  Future<void> freshBiometric() async {
    isSupportedBiometric.value = await BiometricManager().isDeviceSupported();
    biometricType.value = await BiometricManager().checkDeviceBiometric();
  }

  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;
  }

  Future<void> onLoginPressed(String phone) async {
    if (password.value.isEmpty) return;
    showLoading();
    final response = await client.login(phone, password.value);
    hideLoading();
    _handleLoginResponse(response, phone);
  }

  Future<void> _getUserProfile() async {
    showLoading();
    final response = await client.getUserProfile();
    final userProfile = response.data;
    if (response.isSuccess && userProfile != null) {
      await DataPreference.instance.saveUserProfile(userProfile);
      hideLoading();
      Get.offAllNamed(mainScreen);
    } else {
      hideLoading();
      await DataPreference.instance.clearLoginToken();
      final mgs = response.errorMessage ?? Constants.commonError;
      onShowAlertError?.call(mgs);
    }
  }

  void onChangePhonePressed() {
    if (Get.key.currentState?.canPop() == true) {
      Get.back();
    } else {
      DataPreference.instance.clearData();
      Get.offAllNamed(onboardingScreen);
    }
  }

  Future<void> onForgotPassPressed(String phone) async {
    showLoading();
    final response = await client.otpCreateNew(phone);
    hideLoading();
    if (!response.isSuccess) return;
    Get.to(
      OtpScreen(
        repository: ForgotPassOTPRepository(phone, response.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!);
      // Upload FCM token after login
      await PushTokenService.uploadIfLogged();
      await _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 isSupported = await BiometricManager().isDeviceSupported();
    if (!isSupported) {
      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;
    }
    showLoading();
    final response = await client.loginWithBiometric(phone);
    hideLoading();
    _handleLoginResponse(response, phone);
  }
}
