import 'dart:async';

import 'package:fis_common/extensions/string.dart';
import 'package:fis_common/helpers/encrypt.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:flutter/cupertino.dart';
import 'package:flyinsono/architecture/define.dart';
import 'package:flyinsono/architecture/router/index.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/managers/server_config_manager.dart';
import 'package:flyinsono/rpc.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_jsonrpc/services/index.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/pages/auth/auth_board/controller.dart';
import 'package:flyinsono/pages/auth/widgets/form_validator.dart';
import 'package:get/get.dart';
import 'package:fis_jsonrpc/exception.dart';
import 'state.dart';

///登出界面依控制器
class SignUpController extends FControllerBase {
  static const C_VERIFICATION_CONTROLLER_TAG = "sign_up";

  /// 数据状态
  final state = SignUpState();

  /// 表单编辑状态
  final formEditState = SignUpFormEditState();

  /// 表单验证状态
  late final formValidateState = SignUpFormValidateState(state);

  // 文本框控制器
  final accountTextController = TextEditingController();
  final verificationCodeTextController = TextEditingController();
  final passwordTextController = TextEditingController();
  final reenterPasswordTextController = TextEditingController();

  // 文本框焦点
  final accountFocusNode = FocusNode();
  final verificationCodeFocusNode = FocusNode();
  final passwordFocusNode = FocusNode();
  final reenterPasswordFocusNode = FocusNode();

  //  表单验证控制器
  final accountValidatorController = FFormItemValidatorController();
  final passwordValidatorController = FFormItemValidatorController();
  final reenterPasswordValidatorController = FFormItemValidatorController();

  Future<void> checkUserNameExist() async {
    if (formValidateState.asyncValidating) return;
    if (formValidateState.accountBeOccupied) return;
    if (!formValidateState.accountIsNotEmpty) return;
    if (!formValidateState.accountFormatCheck) return;

    formValidateState.asyncValidating = true;
    try {
      final result = await rpc.login.verifyAccountAsync(
        VerifyAccountRequest(userName: state.account),
      );
      if (!result) {
        formValidateState.accountBeOccupied = true;
        // PromptBox.toast(i18nBook.auth.toast4AccountHasExist.t);
        accountValidatorController
            .showCustomError(i18nBook.auth.toast4AccountHasExist.t);
        accountValidatorController.hide();
      } else {
        accountValidatorController.removeCustomError();
        accountValidatorController.hide();
      }
    } catch (e) {
      logger.e("Register: username error", e);
    }
    formValidateState.asyncValidating = false;
  }

  /// 点击获取验证码
  Future<bool> onFetchCodeClick() async {
    final account = state.account;
    bool canSend = false;
    if (account.isNotEmpty) {
      if (i18nBook.isCurrentChinese && ServerConfigManager.isSMSOn) {
        canSend = account.isEmail || account.isChineseMobileNumber;
      } else {
        canSend = account.isEmail;
      }
    }
    if (!canSend) {
      formEditState.accountEdited = true;
      if (ServerConfigManager.isSMSOn) {
        PromptBox.toast(i18nBook.auth.toast4AccountDouble.t);
      } else {
        PromptBox.toast(i18nBook.auth.enterValidEmail.t);
      }
      return false;
    }

    hideFormValidator();
    unfocusForm();

    setBusy(i18nBook.auth.sendingVerificationCode.t);
    final isMobileAccount = account.isChineseMobileNumber;
    bool valid = false;
    try {
      if (isMobileAccount) {
        valid = await rpc.login.sendSMSVerificationCodeAsync(
          SendSMSVerificationCodeRequest(userPhone: account),
        );
      } else {
        valid = await rpc.login.sendEmailVerificationCodeAsync(
          SendEmailVerificationCodeRequest(
            emailAddress: account,
            languageCode: i18nBook.locale.toCodeString('-'),
          ),
        );
      }
      if (valid) {
        PromptBox.toast(i18nBook.auth.toast4VerifyCodeSendSuccess.t);
        return true;
      }
    } catch (e) {
      logger.e(
          "User registration：Send${isMobileAccount ? 'short message' : 'email'} verification code exception",
          e);
    }
    PromptBox.toast(i18nBook.auth.toast4VerifyCodeSendFail.t);
    busy = false;
    return false;
  }

  /// 提交
  Future<void> onSubmit() async {
    if (formValidateState.isCanSubmit) {
      _checkCodeRowShow();
      if (!formValidateState.isCanSubmit) return;
    }

    final formValid = _validateForm();
    if (!formValid) return;

    state.onSubmit = true;
    hideFormValidator();
    unfocusForm();
    await checkUserNameExist();
    if (formValidateState.accountBeOccupied) return;

    var account = '';
    final password = state.password;
    final code = state.isShowCodeRow ? state.verificationCode : "";
    String? errMsg;
    account = state.account;
    try {
      var pas = FEncryptHelper.symmetryEncrypt(password);
      print(pas);
      final result = await rpc.login.commonSignUpAsync(
        CommonSignUpRequest(
          anyAccount: account,
          anyCode: state.isShowCodeRow ? code : '',
          password: pas,
        ),
      );
      if (result) {
        state.onSubmit = false;
        PromptBox.toast(i18nBook.auth.toast4SignUpSuccess.t);
        Store.user.handleRegistrationEvent(account: state.account);
        return onRouteBack(
          parameters: {
            "signup_account": state.account,
          },
          clearForm: true,
        );
      }
    } on JsonRpcNetworkException catch (_) {
      PromptBox.toast(i18nBook.auth.toast4SignUpFailNetworkIssues.t);
    } catch (e) {
      logger.e("register error", e);
    }
    state.onSubmit = false;
  }

  bool _validateForm() {
    if (!formValidateState.accountChecked) {
      showAccountValidator();
      return false;
    }
    if (!formValidateState.pwdChecked) {
      showPwdValidator();
      return false;
    }
    if (!formValidateState.reenterPwdChecked) {
      showReenterPwdValidator();
      return false;
    }

    // 验证勾选用户条款
    if (!state.isAgreeClause) {
      logger.i("AgreeClause Validation failed on submit sign up");
      hideFormValidator();
      PromptBox.toast(i18nBook.auth.toast4AgreeStatement.t);
      return false;
    }

    return true;
  }

  /// 路由返回
  void onRouteBack({Map<String, String>? parameters, bool clearForm = false}) {
    Get.find<AuthBoardController>()
        .changePageByName(RouteNames.Auth.SignIn, parameters: parameters);
    formEditState.clear();
    if (clearForm) {
      state.reset();
      // 控制器也要清除，不然状态就不一致
      accountTextController.clear();
      verificationCodeTextController.clear();
      passwordTextController.clear();
      reenterPasswordTextController.clear();
    }
  }

  /// 条款选择框切换
  void onAgreeClauseChanged(bool val) {
    state.isAgreeClause = val;
  }

  /// 检测验证码栏是否需要显示
  void _checkCodeRowShow() {
    final account = state.account;
    state.isShowCodeRow =
        account.isEmpty || account.isChineseMobileNumber || account.isEmail;
  }

  /// 展示账号验证器
  void showAccountValidator() {
    if (formValidateState.accountBeOccupied) {
      accountValidatorController.hide();
      return;
    }
    if (state.account.isEmpty) {
      accountValidatorController.resetValidate();
    } else {
      accountValidatorController.validate();
    }
  }

  /// 展示密码验证器
  void showPwdValidator() {
    if (state.password.isEmpty) {
      passwordValidatorController.resetValidate();
    } else {
      passwordValidatorController.validate();
    }
  }

  /// 展示确认密码验证器
  void showReenterPwdValidator() {
    if (state.reenterPassword.isEmpty) {
      reenterPasswordValidatorController.resetValidate();
    } else {
      reenterPasswordValidatorController.validate();
    }
  }

  /// 隐藏表单验证提示
  void hideFormValidator() {
    accountValidatorController.hide();
    passwordValidatorController.hide();
    reenterPasswordValidatorController.hide();
  }

  /// 表单失焦
  void unfocusForm() {
    accountFocusNode.unfocus();
    passwordFocusNode.unfocus();
    reenterPasswordFocusNode.unfocus();
    verificationCodeFocusNode.unfocus();
  }

  /// 监听焦点状态
  void _listenFocusNodes() {
    accountFocusNode.addListener(() {
      if (accountFocusNode.hasFocus) {
        formEditState.accountEdited = true;
        showAccountValidator();
      } else {
        _checkCodeRowShow();
        accountValidatorController.hide();
        checkUserNameExist();
      }
    });
    passwordFocusNode.addListener(() {
      if (passwordFocusNode.hasFocus) {
        formEditState.pwdEdited = true;
        // form布局可能因为验证码栏出现位移，延时计算提示位置
        Future.delayed(Duration(milliseconds: 100), showPwdValidator);
      } else {
        passwordValidatorController.hide();
      }
    });
    reenterPasswordFocusNode.addListener(() {
      if (reenterPasswordFocusNode.hasFocus) {
        formEditState.reenterPwdEdited = true;
        // form布局可能因为验证码栏出现位移，延时计算提示位置
        Future.delayed(Duration(milliseconds: 100), showReenterPwdValidator);
      } else {
        reenterPasswordValidatorController.hide();
      }
    });
    verificationCodeFocusNode.addListener(() {
      if (verificationCodeFocusNode.hasFocus) {
        formEditState.verificationCodeEdited = true;
      }
    });
  }

  /// 释放资源
  void _doDispose() {
    // 释放焦点
    accountFocusNode.dispose();
    passwordFocusNode.dispose();
    reenterPasswordFocusNode.dispose();
    verificationCodeFocusNode.dispose();
    // 释放文本框控制器
    verificationCodeTextController.dispose();
    accountTextController.dispose();
    passwordTextController.dispose();
    reenterPasswordTextController.dispose();
    // 释放表单验证控制器
    accountValidatorController.dispose();
    passwordValidatorController.dispose();
    reenterPasswordValidatorController.dispose();
  }

  @override
  void onInit() {
    super.onInit();
    _listenFocusNodes();
  }

  @override
  void onClose() {
    _doDispose();
    super.onClose();
  }
}
