security_email_controller.dart 3.75 KB
import 'dart:async';

import 'package:doublefeel_flutter/app/modules/home/widgets/my/security_email_views.dart';
import 'package:doublefeel_flutter/core/util/app_toast.dart';
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';

class AddSecurityEmailController extends GetxController {
  static final _emailPattern = RegExp(
    r'^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$',
  );
  static const resendSeconds = 60;

  final emailController = TextEditingController();
  final codeController = TextEditingController();

  final hasSubmittedEmail = false.obs;
  final emailInput = ''.obs;
  final codeInput = ''.obs;
  final secondsRemaining = resendSeconds.obs;

  Timer? _resendTimer;

  static final _passwordRegex = RegExp(
    r'^(?=.*[0-9])(?=.*[A-Z]).{6,}$',
  );

  final passwordController = TextEditingController();
  final passwordInput = ''.obs;
  final isPasswordObscured = true.obs;

  final confirmPasswordController = TextEditingController();
  final confirmPasswordInput = ''.obs;
  final isConfirmPasswordObscured = true.obs;

  @override
  void onInit() {
    super.onInit();
    emailController.addListener(_onEmailChanged);
    codeController.addListener(_onCodeChanged);
    passwordController.addListener(_onPasswordChanged);
    confirmPasswordController.addListener(_onConfirmPasswordChanged);
  }

  void _onEmailChanged() {
    emailInput.value = emailController.text.replaceAll(' ', '').trim();
  }

  void _onCodeChanged() {
    codeInput.value = codeController.text.trim();
  }

  void _onPasswordChanged() {
    passwordInput.value = passwordController.text.trim();
  }

  void _onConfirmPasswordChanged() {
    confirmPasswordInput.value = confirmPasswordController.text.trim();
  }

  bool get isEmailValid => _emailPattern.hasMatch(emailInput.value);

  bool get isPasswordValid =>
      _passwordRegex.hasMatch(passwordInput.value) &&
      passwordInput.value.isNotEmpty;

  bool get isConfirmPasswordValid =>
      _passwordRegex.hasMatch(confirmPasswordInput.value) &&
      confirmPasswordInput.value.isNotEmpty &&
      confirmPasswordInput.value == passwordInput.value;

  bool get canSetPassword => isPasswordValid && isConfirmPasswordValid;

  bool get showError => hasSubmittedEmail.value && !isEmailValid;

  bool get canSubmitCode => codeInput.value.isNotEmpty;

  void togglePasswordVisibility() {
    isPasswordObscured.value = !isPasswordObscured.value;
  }

  void toggleConfirmPasswordVisibility() {
    isConfirmPasswordObscured.value = !isConfirmPasswordObscured.value;
  }

  void sendVerificationEmail() {
    hasSubmittedEmail.value = true;
    if (!isEmailValid) return;

    startResendCountdown();
    Get.to(() => const SecurityEmailVerificationView());
  }

  void startResendCountdown() {
    _resendTimer?.cancel();
    secondsRemaining.value = resendSeconds;
    _resendTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
      if (secondsRemaining.value <= 1) {
        timer.cancel();
        secondsRemaining.value = 0;
        return;
      }
      secondsRemaining.value -= 1;
    });
  }

  void submitCode(BuildContext context) {
    if (!canSubmitCode) return;
    FocusScope.of(context).unfocus();
    Get.to(() => const SetSecurityEmailPasswordView());
  }

  void setPassword(BuildContext context) {
    if (!canSetPassword) return;
    FocusScope.of(context).unfocus();
    AppToast.show(context.l10n.settingsSaved);
    TextInput.finishAutofillContext();
    Get.back();
    Get.back();
    Get.back();
  }

  @override
  void onClose() {
    _resendTimer?.cancel();
    emailController.dispose();
    codeController.dispose();
    passwordController.dispose();
    confirmPasswordController.dispose();
    super.onClose();
  }
}