import 'package:flutter/material.dart';

class ValidatorProvider extends ChangeNotifier {
  final Map<String, String?> _errors = {};
  final Map<String, bool> _obscureFields = {};
  final Map<String, FocusNode?> _focusNodes = {};
  final Map<String, TextEditingController> _controllers = {};
  String? _password;

  bool validateAllFields() {
    bool isValid = true;

    // Validasi email
    final emailError = emailValidator(_controllers['email']?.text);
    _errors['email'] = emailError;
    if (emailError != null) isValid = false;

    // Validasi nama lengkap
    final fullNameError = fullNameValidator(_controllers['fullname']?.text);
    _errors['fullname'] = fullNameError;
    if (fullNameError != null) isValid = false;

    // Validasi password (jika ada)
    if (_controllers.containsKey('password')) {
      final passwordError = passwordValidator(_controllers['password']?.text);
      _errors['password'] = passwordError;
      if (passwordError != null) isValid = false;
    }

    // Validasi konfirmasi password (jika ada)
    if (_controllers.containsKey('confirmPassword')) {
      final confirmPasswordError =
          confirmPasswordValidator(_controllers['confirmPassword']?.text);
      _errors['confirmPassword'] = confirmPasswordError;
      if (confirmPasswordError != null) isValid = false;
    }

    // Validasi NISN (jika ada)
    if (_controllers.containsKey('nisn')) {
      final nisnError = nisnValidator(_controllers['nisn']?.text);
      _errors['nisn'] = nisnError;
      if (nisnError != null) isValid = false;
    }

    notifyListeners();
    return isValid;
  }

  // Mengambil error untuk field tertentu
  String? getError(String field) => _errors[field];

  // Memeriksa apakah field tertentu sedang disembunyikan (obscure)
  bool isObscure(String field) => _obscureFields[field] ?? true;

  // Mengambil FocusNode untuk field tertentu
  FocusNode? getFocusNode(String field) => _focusNodes[field];

  // Toggle visibility untuk field tertentu
  void toggleVisibility(String field) {
    _obscureFields[field] = !(isObscure(field));
    notifyListeners();
  }

  // Mengatur FocusNode untuk field tertentu
  void setFocusNode(String field, FocusNode focusNode) {
    _focusNodes[field] = focusNode;
    notifyListeners();
  }

  // Validasi field tertentu dengan validator yang diberikan
  void validateField(String field, String? value,
      {String? Function(String?)? validator}) {
    // Jika validator tidak null, gunakan untuk memvalidasi nilai field
    final error = validator != null ? validator(value) : null;
    _errors[field] = error;

    // Simpan password jika field adalah 'password'
    if (field == 'password') {
      _password = value;
    }

    // Validasi confirm password jika field adalah 'confirmPassword'
    if (field == 'confirmPassword') {
      _errors[field] = confirmPasswordValidator(value);
    }

    notifyListeners();
  }

  // Reset the fields and clear errors
  void resetFields() {
    _errors.clear();
    _obscureFields.clear();
    _password = null;

    for (final controller in _controllers.values) {
      controller.clear();
    }

    notifyListeners();
  }

  // Set TextEditingController for a field
  void setController(String field, TextEditingController controller) {
    _controllers[field] = controller;
  }

  // Remove TextEditingController when not needed anymore
  void removeController(String field) {
    _controllers.remove(field);
  }

  @override
  void dispose() {
    // Dispose controllers and focus nodes
    for (final controller in _controllers.values) {
      controller.dispose();
    }
    for (final focusNode in _focusNodes.values) {
      focusNode?.dispose();
    }
    _controllers.clear();
    _focusNodes.clear();
    super.dispose();
  }

  // Validator email
  String? emailValidator(String? value) {
    if (value == null || value.isEmpty) {
      return 'Email cannot be empty';
    }
    const emailRegex = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$";
    if (!RegExp(emailRegex).hasMatch(value)) {
      return 'Invalid email format (e.g. example@gmail.com)';
    }
    return null;
  }

  // Validator password
  String? passwordValidator(String? value) {
    if (value == null || value.isEmpty) {
      return 'Password cannot be empty';
    } else if (value.length < 8) {
      return 'Password must be at least 8 characters long';
    }
    _password = value;
    return null;
  }

  // Validator untuk konfirmasi password
  String? confirmPasswordValidator(String? value) {
    if (value == null || value.isEmpty) {
      return 'Please confirm your password';
    } else if (value != _password) {
      return 'Passwords do not match';
    }
    return null;
  }

  // Validator NISN
  String? nisnValidator(String? value) {
    if (value == null || value.isEmpty) {
      return 'NISN cannot be empty';
    } else if (value.length != 10 || !RegExp(r'^\d{10}$').hasMatch(value)) {
      return 'NISN must be exactly 10 digits';
    }
    return null;
  }

  // Validator nama lengkap
  String? fullNameValidator(String? value) {
    if (value == null || value.isEmpty) {
      return 'Full name cannot be empty';
    }
    return null;
  }

  // Menghapus error dari field tertentu
  void clearError(String field) {
    _errors[field] = null;
    notifyListeners();
  }

  // Menghapus semua error
  void clearErrors() {
    _errors.clear();
    notifyListeners();
  }

  // Menghapus FocusNode saat tidak diperlukan lagi
  void disposeFocusNodes() {
    for (final focusNode in _focusNodes.values) {
      focusNode?.dispose();
    }
    _focusNodes.clear();
    notifyListeners();
  }
}
