import 'package:get/get.dart';
import 'package:mypoint_flutter_app/app/config/constants.dart';
import 'package:mypoint_flutter_app/core/network/restful_api_client_all_request.dart';
import 'package:mypoint_flutter_app/features/otp/forgot_pass_otp_repository.dart';
import 'package:mypoint_flutter_app/features/otp/otp_screen.dart';
import 'package:mypoint_flutter_app/shared/router_gage.dart';
import '../../core/network/restful_api_viewmodel.dart';
import '../../core/services/biometric_manager.dart';
import '../../shared/preferences/data_preference.dart';
import '../../core/services/login_service.dart';
import '../otp/model/create_otp_response_model.dart';

enum LoginState { idle, typing, error }

class LoginViewModel extends RestfulApiViewModel {
  final Rx<LoginState> loginState = LoginState.idle.obs;
  final RxBool isPasswordVisible = false.obs;
  final RxString password = "".obs;
  final RxBool isSupportedBiometric = false.obs;
  final Rx<BiometricTypeEnum> 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();
    final result = await _loginService.login(phone, password.value);
    hideLoading();
    _handleLoginResult(result, phone);
  }

  /// 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;
        onShowAlertError?.call(result.message ?? Constants.commonError);
        break;
      case LoginResult.networkError:
      case LoginResult.unknownError:
      default:
        onShowAlertError?.call(result.message ?? Constants.commonError);
        break;
    }
  }

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

  Future<void> onForgotPassPressed(String phone) async {
    await callApi<CreateOTPResponseModel>(
      request: () => client.otpCreateNew(phone),
      onSuccess: (data, _) {
        Get.to(OtpScreen(repository: ForgotPassOTPRepository(phone, data.resendAfterSecond ?? Constants.otpTtl)));
      },
      onFailure: (msg, _, _) async {
        onShowAlertError?.call(msg);
      },
    );
  }

  /// 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();
    final result = await _loginService.biometricLogin(phone);
    hideLoading();
    _handleLoginResult(result, phone);
  }
}
