import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:injectable/injectable.dart';
import 'package:keyboard/base/base_controller.dart';
import 'package:keyboard/dialog/login/login_dialog.dart';

import '../../data/consts/error_code.dart';
import '../../data/repository/account_repository.dart';
import '../../dialog/privacy_agreement_dialog.dart';
import '../../handler/wechat_login_service.dart';
import '../../resource/string.gen.dart';
import '../../utils/error_handler.dart';
import '../../utils/http_handler.dart';
import '../../utils/toast_util.dart';

@injectable
class LoginController extends BaseController {
  final AccountRepository accountRepository;
  final WechatLoginService wechatLoginService;
  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 _isAgree = false.obs;

  bool get isAgree => _isAgree.value;

  final RxBool _isFirstSend = true.obs;

  bool get isFirstSend => _isFirstSend.value;

  LoginController(this.accountRepository, this.wechatLoginService);

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

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

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

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

  void clickAgree() {
    _isAgree.value = !_isAgree.value;
  }

  void onSendVerificationCode() async {
    if (_countDown.value != null) {
      return;
    }
    if (!RegExp(r'^1\d{10}$').hasMatch(phone)) {
      ToastUtil.show(StringName.loginPrintPhoneVerification);
      return;
    }
    if (!_isAgree.value) {
      PrivacyAgreementDialog.show(
        btnConfirm: () async {
          _isAgree.value = true;
          onSendVerificationCode();
        },
      );
      return;
    }

    try {
      await accountRepository.loginSendCode(phone);
      _countDown.value = _countDownTime;
      _startCountDown();
    } catch (error) {
      if (error is RequestCodeTooOftenException) {
        ToastUtil.show(StringName.loginRequestCodeFrequentlyToast);
      } else if (error is ServerErrorException) {
        ToastUtil.show(error.message);
      } else {
        ToastUtil.show(StringName.loginVerificationCodeRequestFailedToast);
      }
    }
  }

  void onLoginClick() {
    if (!RegExp(r'^1\d{10}$').hasMatch(phone)) {
      ToastUtil.show(StringName.loginPrintPhoneVerification);
      return;
    }
    if (!_isAgree.value) {
      PrivacyAgreementDialog.show(
        btnConfirm: () async {
          _isAgree.value = true;
          onLoginClick();
        },
      );
      ToastUtil.show(StringName.loginAgreePrivacy);
      return;
    }
    if (code.isEmpty) {
      ToastUtil.show(StringName.loginPrintVerificationCode);
      return;
    }
    accountRepository
        .loginUserLogin(phone, code)
        .then((data) {
          Get.back();
          ToastUtil.show(StringName.loginSuccess);
        })
        .catchError((error) {
          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 {
            ErrorHandler.toastError(error);
          }
        });
  }

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

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

  @override
  void onClose() {
    super.onClose();
    _countDown.value = null;
  }

  void clickWxLogin() async {
    if (!_isAgree.value) {
      Get.back();
      LoginDialog.show();
      return;
    }

  }


}
