import 'dart:async';

import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:injectable/injectable.dart';
import 'package:location/base/base_controller.dart';
import 'package:location/data/consts/error_code.dart';
import 'package:location/resource/string.gen.dart';
import 'package:location/sdk/quicklogin/quick_login_helper.dart';
import 'package:location/utils/atmob_log.dart';
import 'package:location/utils/http_handler.dart';
import 'package:location/utils/toast_util.dart';
import '../../data/repositories/account_repository.dart';
import '../../utils/de_bounce.dart';

@injectable
class LoginController extends BaseController {
  final RxString _phone = ''.obs;
  final RxString _code = ''.obs;

  String get phone => _phone.value;

  String get code => _code.value;

  final int _countDownTime = 60;
  final RxnInt _countDown = RxnInt();

  int? get countDown => _countDown.value;

  final RxBool _isAgreePrivacy = false.obs;

  bool get isAgreePrivacy => _isAgreePrivacy.value;

  final AccountRepository accountRepository;

  LoginController(this.accountRepository);

  final Debounce _saveDebounce = Debounce(debounceTime: 1000);
  bool isRequestLogin = false;

  final Rx<LoginStatus> _loginStatus = Rx(LoginStatus.loading);

  LoginStatus get loginStatus => _loginStatus.value;

  final RxBool _isSupportOneLogin = RxBool(false);

  bool get isSupportOneLogin => _isSupportOneLogin.value;

  bool? _isOneLoginSuccess;

  StreamSubscription? eventOneLoginSubscription;

  @override
  void onReady() {
    super.onReady();
    QuickLoginHelper.preFetchNumber(onSuccess: (token) {
      _isSupportOneLogin.value = true;
      onePassLogin();
    }, onError: (errorMsg) {
      _loginStatus.value = LoginStatus.codeLogin;
    });

    eventOneLoginSubscription = QuickLoginHelper.getEventChannel()
        .receiveBroadcastStream()
        .listen(_onOneLoginData);
  }

  void _onOneLoginData(response) {
    AtmobLog.d('LoginController', 'response:$response');
    if (response is Map) {
      var action = (response)["action"];
      switch (action) {
        case "authViewWillAppear":
          _loginStatus.value = LoginStatus.oneLogin;
          break;
        case "authViewWillDisappear":
          if (_isOneLoginSuccess != true &&
              loginStatus == LoginStatus.oneLogin) {
            Get.back();
          }
        case "code_login":
          QuickLoginHelper.closeLoginAuthView();
          _loginStatus.value = LoginStatus.codeLogin;
          break;
      }
    }
  }

  void onePassLogin() {
    //尝试打开一键登录页面
    QuickLoginHelper.onePassLogin(onSuccess: (ydToken, accessToken) {
      _isOneLoginSuccess = true;
      accountRepository
          .oneClickLogin(token: ydToken, accessToken: accessToken)
          .then((_) {
        QuickLoginHelper.closeLoginAuthView();
        Get.back();
      }).catchError((error) {
        _loginStatus.value = LoginStatus.codeLogin;
        ToastUtil.show(StringName.oneLoginError);
      });
    }, onError: (msg) {
      _loginStatus.value = LoginStatus.codeLogin;
      ToastUtil.show(StringName.oneLoginError);
    });
  }

  void onPhoneChanged(String value) {
    _phone.value = value;
  }

  void onCodeChanged(String value) {
    _code.value = value;
  }

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

  void onSendVerificationCode() {
    _saveDebounce.onClick(() {
      sendVerificationCode();
    });
  }

  void sendVerificationCode() {
    if (_countDown.value != null) {
      return;
    }
    if (!RegExp(r'^1\d{10}$').hasMatch(phone)) {
      ToastUtil.show(StringName.loginPrintPhoneVerification);
      return;
    }
    if (!isAgreePrivacy) {
      ToastUtil.show(StringName.loginAgreePrivacy);
      return;
    }
    accountRepository.loginSendCode(phone).then((value) {
      _countDown.value = _countDownTime;
      _startCountDown();
    }).catchError((error) {
      if (error is RequestCodeTooOftenException) {
        ToastUtil.show(StringName.loginRequestCodeFrequentlyToast);
        return;
      }
      if (error is ServerErrorException) {
        ToastUtil.show(error.message);
      } else {
        ToastUtil.show(StringName.loginVerificationCodeRequestFailedToast);
      }
    });
  }

  void _startCountDown() {
    Future.delayed(Duration(seconds: 1), () {
      int? time = _countDown.value;
      if (time != null) {
        _countDown.value = time - 1;
        if (time > 0) {
          _startCountDown();
        } else {
          _countDown.value = null;
        }
      }
    });
  }

  void onPrivacyClick() {
    _isAgreePrivacy.value = !_isAgreePrivacy.value;
  }

  void onLoginClick() {
    _saveDebounce.onClick(() {
      login();
    });
  }

  void login() {
    if (isRequestLogin) {
      return;
    }
    if (!RegExp(r'^1\d{10}$').hasMatch(phone)) {
      ToastUtil.show(StringName.loginPrintPhoneVerification);
      return;
    }
    if (!isAgreePrivacy) {
      ToastUtil.show(StringName.loginAgreePrivacy);
      return;
    }
    if (code.isEmpty) {
      ToastUtil.show(StringName.loginPrintVerificationCode);
      return;
    }
    isRequestLogin = true;
    accountRepository.loginUserLogin(phone, code).then((data) {
      Get.back(result: true);
      ToastUtil.show(StringName.loginSuccess);
    }).catchError((error) {
      isRequestLogin = false;
      if (error is LoginTooOftenException) {
        ToastUtil.show(StringName.loginTooOftenToast);
        return;
      }
      if (error is ServerErrorException) {
        if (error.code == ErrorCode.verificationCodeError) {
          ToastUtil.show(StringName.loginVerificationCodeErrorToast);
        } else {
          ToastUtil.show(error.message);
        }
      } else {
        ToastUtil.show(StringName.loginFailedToast);
      }
    });
  }

  void onOneLoginClick() {
    onePassLogin();
  }

  @override
  void onClose() {
    super.onClose();
    _countDown.value = null;
    eventOneLoginSubscription?.cancel();
    QuickLoginHelper.dispose();
  }
}

enum LoginStatus { loading, codeLogin, oneLogin }
