import 'dart:convert';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:o2oa_all_platform/common/index.dart';

import '../../environment_config.dart';
import '../common/inner_webview/index.dart';
import 'index.dart';
import 'server_info/index.dart';

class LoginController extends GetxController {
  LoginController();

  final state = LoginState();

  // 登录用户名的控制器
  final TextEditingController userNameController = TextEditingController();
  // 验证码的控制器
  final TextEditingController codeController = TextEditingController();
  // 密码的控制器
  final TextEditingController passwordController = TextEditingController();
  // 图片验证码的控制器
  final TextEditingController captchaController = TextEditingController();

  final TextEditingController twoFactorCodeController = TextEditingController();

  // 密码输入框
  final FocusNode passwordNode = FocusNode();
  // 验证码的输入框
  final FocusNode codeNode = FocusNode();
  // 图片验证码输入框
  final FocusNode captchaNode = FocusNode();

  // 图片验证码对象
  CaptchaImgData? _captchaImgData;
  // 登录加密
  RSAPublicKeyData? _publicKeyData;
  // 双因素认证
  bool isTwoFactorAuth = false;

  /// 登录加密服务
  void loadRSAPublicKey() async {
    _publicKeyData = await OrgAuthenticationService.to.getRSAPublicKey();
  }

  /// 登录模式查询，是否开启短信验证码登录，是否显示图片验证码等
  void loadLoginMode() async {
    LoginModeData? data = await OrgAuthenticationService.to.getLoginMode();
    if (data != null) {
      var iscode = data.codeLogin ?? false;
      var isCaptcha = data.captchaLogin ?? false;
      isTwoFactorAuth = data.twoFactorLogin ?? false;
      if (isTwoFactorAuth) {
        iscode = false; // 双因素认证和短信验证码互斥
      }
      if (iscode) {
        state.isShowChangeLoginModeButton = true;
      }
      if (isCaptcha) {
        state.isCaptcha = true;
        getCaptchaImageData();
      }
      OLogger.d(
          "登录模式： code： $iscode captcha: $isCaptcha isTwoFactorAuth: $isTwoFactorAuth");
    }
  }

  /// 是否能注册
  Future<void> loadRegisterMode() async {
    ValueStringData? data = await OrganizationPersonalService.to.registerMode();
    OLogger.d("注册模式：${data?.value} ");
    if (data != null &&
        data.value?.isNotEmpty == true &&
        data.value != O2.registerModeDisable) {
      state.registerEnable = true;
    }
  }

  /// 获取图片验证码
  void getCaptchaImageData() async {
    _captchaImgData =
        await OrgAuthenticationService.to.getLoginCaptchaImgData(100, 50);
    if (_captchaImgData != null) {
      captchaController.clear();
      state.captchaBase64String = _captchaImgData?.image ?? '';
    } else {
      OLogger.e('获取图片验证码失败！');
    }
  }

  /// 解析图片验证码
  Uint8List parseCaptchaImg() {
    return base64Decode(state.captchaBase64String);
  }

  /// 检查手机号码
  bool onCheckMobile() {
    var phone = userNameController.value.text;
    if (phone.isEmpty) {
      Loading.toast('login_form_user_name_not_empty'.tr);
      return false;
    }
    return true;
  }

  /// 发送短信验证码
  void sendSmsCode() async {
    var mobile = userNameController.value.text;
    if (mobile.isEmpty) {
      Loading.toast('login_form_user_name_not_empty'.tr);
      return;
    }
    Loading.show();
    var res = await OrgAuthenticationService.to.getPhoneCode(mobile);
    Loading.dismiss();
    if (res != null) {
      if (Get.context != null) {
        FocusScope.of(Get.context!).requestFocus(codeNode);
      }
      Loading.toast('bind_send_code_success'.tr);
    }
  }

  /// 登录
  Future<void> login() async {
    if (state.isVisibleAgree && !state.isAgree) {
      Loading.showError('privacy_policy_bind_disagree_alert'.tr);
      return;
    }
    var username = userNameController.value.text;
    var code = codeController.value.text;
    var password = passwordController.value.text;
    var captcha = captchaController.value.text;
    if (username.isEmpty) {
      Loading.toast('login_form_user_name_not_empty'.tr);
      return;
    }
    if (state.isPasswordLogin) {
      // 密码登录
      if (password.isEmpty) {
        Loading.toast('login_form_user_password_not_empty'.tr);
        return;
      }
      if (state.isCaptcha && captcha.isEmpty) {
        Loading.toast('login_form_user_code_not_empty'.tr);
        return;
      }
      Loading.show();
      var form = LoginForm();
      form.credential = username;
      form.password = password;
      if (state.isCaptcha && _captchaImgData != null) {
        form.captcha = _captchaImgData?.id;
        form.captchaAnswer = captcha;
      }
      if (_publicKeyData != null &&
          _publicKeyData?.publicKey != null &&
          _publicKeyData!.publicKey!.isNotEmpty &&
          _publicKeyData!.rsaEnable == true) {
        form.isEncrypted = O2.rsaEncryptedYes;
        //加密密码
        String publicKey = _publicKeyData!.publicKey!;
        String key = await RSACryptUtil.encodeString(password, publicKey);
        form.password = key;
      } else {
        form.isEncrypted = O2.rsaEncryptedNo;
      }
      if (isTwoFactorAuth) {
        // 双因素认证
        _loginTwofactorStepOne(form);
      } else {
        _loginByPassword(form);
      }
    } else {
      // 短信验证码登录
      if (code.isEmpty) {
        Loading.toast('login_form_user_code_not_empty'.tr);
        return;
      }
      Loading.show();
      O2Person? person =
          await OrgAuthenticationService.to.loginWithCode(username, code);
      if (person != null) {
        Loading.dismiss();
        // 登录成功
        Get.offNamed(O2OARoutes.home);
      }
    }
  }
  /// 密码登录认证请求
  Future<void> _loginByPassword(LoginForm form) async {
    O2Person? person = await OrgAuthenticationService.to.login(form);
    if (person != null) {
      Loading.dismiss();
      // 登录成功
      Get.offNamed(O2OARoutes.home);
    } else {
      _loginFailRefreshCaptcha();
    }
  }
  /// 双因素认证第一步 请求
  Future<void> _loginTwofactorStepOne(LoginForm form) async {
    TwoFactorStepOneResponse? data =
        await OrgAuthenticationService.to.loginTwofactorStepOne(form);
    if (data != null) {
      Loading.dismiss();
      OLogger.d('双因素认证，进入第二步！');
      if (data.value == true) {
        state.twoFactorLogin = true;
        Loading.toast('bind_send_code_success'.tr);
      } else {
        OLogger.i('这里认证失败，可能是密码过期之类的错误');
        Loading.toast('login_auth_failed'.tr);
        _loginFailRefreshCaptcha();
      }
    } else {
      _loginFailRefreshCaptcha();
    }
  }

  void _loginFailRefreshCaptcha() {
      // 登录错误，如果有验证码需要刷新，不然还是老的验证码无法使用
      if (state.isCaptcha) {
        OLogger.d("认证失败，刷新验证码");
        getCaptchaImageData();
      }
  }

  /// 双因素认证第二步 点击登录
  Future<void> loginTwofactorStepTwo() async {
    var code = twoFactorCodeController.value.text;
    var username = userNameController.value.text;
    OLogger.d("双因素认证第二步 username: $username, code: $code ");
    // 短信验证码登录
    if (code.isEmpty) {
      Loading.toast('login_form_user_code_not_empty'.tr);
      return;
    }
    Loading.show();
    O2Person? person =
        await OrgAuthenticationService.to.loginWithCode(username, code);
    if (person != null) {
      Loading.dismiss();
      // 登录成功
      Get.offNamed(O2OARoutes.home);
    }
  }

  /// 返回登录
  void twoFactorBackLogin() {
    OLogger.d("双因素认证返回");
    state.twoFactorLogin = false;
    twoFactorCodeController.text = '';
    _loginFailRefreshCaptcha();
  }

  /// 重新绑定
  void rebind() {
    final context = Get.context;
    if (context == null) {
      return;
    }
    O2UI.showConfirm(context, 'login_form_rebind_confirm_message'.tr,
        okPressed: () => _rebindExecute());
  }

  _rebindExecute() async {
    await O2ApiManager.instance.cleanO2UnitAndSp();
    Get.offNamed(O2OARoutes.splash);
  }

  /// 切换登录模式
  void changeLoginMode() {
    state.isPasswordLogin = !state.isPasswordLogin;
  }

  void openConfig() {
    ServerInfoPage.open();
  }

  /// 同意协议
  void changeAgree(bool? v) {
    state.isAgree = v == true;
  }

  /// 打开用户协议
  void openUserAgreement() {
    InnerWebviewPage.open(O2.userAgreementUrl);
  }

  /// 打开隐私政策
  void openPrivacyPolicy() {
    InnerWebviewPage.open(O2.privacyPolicyUrl);
  }

  void gotoRegister() {
    Get.offAllNamed(O2OARoutes.register);
  }

  /// 在 onInit() 之后调用 1 帧。这是进入的理想场所
  @override
  void onReady() {
    state.isVisibleAgree = EnvironmentConfig.needCheckPrivacyAgree();
    // O2UI.hideStatusBar();
    loadRSAPublicKey();
    loadLoginMode();
    loadRegisterMode();
    state.year = '${DateTime.now().year}';
    super.onReady();
  }

  @override
  void onClose() {
    // O2UI.showStatusBar();
    super.onClose();
  }
}
