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 '../../networking/restful_api_viewmodel.dart';
import '../../permission/biometric_manager.dart';
import '../../preference/data_preference.dart';
import '../../services/login_service.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;
  final LoginService _loginService = LoginService();

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

  /// REFACTORED: Clean login method using LoginService
  Future<void> onLoginPressed(String phone) async {
    if (password.value.isEmpty) return;
    showLoading();
    try {
      final result = await _loginService.login(phone, password.value);
      hideLoading();
      _handleLoginResult(result, phone);
    } catch (e) {
      hideLoading();
      print('Login error: ${e.toString()}');
      onShowAlertError?.call(Constants.commonError);
    }
  }

  /// REFACTORED: Handle login result with proper error handling
  void _handleLoginResult(LoginResponse result, String phone) {
    switch (result.result) {
      case LoginResult.success:
        Get.offAllNamed(mainScreen);
        break;
      case LoginResult.deviceUndefined:
        onShowDeviceError?.call(result.message ?? Constants.commonError);
        break;
      case LoginResult.requiredChangePass:
        onShowChangePass?.call(result.message ?? Constants.commonError);
        break;
      case LoginResult.invalidAccount:
        onShowInvalidAccount?.call(result.message ?? Constants.commonError);
        break;
      case LoginResult.bioTokenInvalid:
        _loginService.clearBiometricToken(phone);
        onShowAlertError?.call(result.message ?? Constants.commonError);
        break;
      case LoginResult.invalidCredentials:
        loginState.value = LoginState.error;
        break;
      case LoginResult.networkError:
      case LoginResult.unknownError:
      default:
        onShowAlertError?.call(result.message ?? Constants.commonError);
        break;
    }
  }

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

  Future<void> onForgotPassPressed(String phone) async {
    showLoading();
    try {
      final response = await client.otpCreateNew(phone);
      hideLoading();
      if (!response.isSuccess) {
        onShowAlertError?.call(response.errorMessage ?? Constants.commonError);
        return;
      }
      Get.to(
        OtpScreen(
          repository: ForgotPassOTPRepository(phone, response.data?.resendAfterSecond ?? Constants.otpTtl),
        ),
      );
    } catch (e) {
      hideLoading();
      print('OTP error: ${e.toString()}');
      onShowAlertError?.call(Constants.commonError);
    }
  }

  /// REFACTORED: Biometric login using LoginService
  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();
    try {
      final result = await _loginService.biometricLogin(phone);
      hideLoading();
      _handleLoginResult(result, phone);
    } catch (e) {
      hideLoading();
      print('Biometric login error: ${e.toString()}');
      onShowAlertError?.call(Constants.commonError);
    }
  }
}
