/**
 * Real-time password validation hints — checks length, uppercase, digit, special char.
 */
import { warnOnce, resolveHost } from '../core/app-dom.js';

const rules = {
  min: (value, min) => value.length >= min,
  upper: (value) => /[A-Z]/.test(value),
  lower: (value) => /[a-z]/.test(value),
  number: (value) => /\d/.test(value),
  symbol: (value) => /[^a-zA-Z0-9]/.test(value),
  email: (value, _min, email) => {
    if (!email) {return true;}
    return !value.toLowerCase().includes(email.toLowerCase());
  },
  match: (_value, _min, _email, confirm) => {
    if (!confirm) {return false;}
    return true;
  }
};

export function initPasswordHints(root = document, options = {}) {
  const selector = String(options.selector || '[data-password-hints]').trim() || '[data-password-hints]';
  const host = resolveHost(root);
  const containers = Array.from(host.querySelectorAll(selector));
  if (!containers.length) {
    return { destroy: () => {} };
  }

  const cleanupFns = [];

  containers.forEach((container) => {
    if (!(container instanceof HTMLElement)) {return;}
    if (container.dataset.passwordHintsBound === '1') {return;}

    const passwordSelector = container.dataset.passwordInput;
    const confirmSelector = container.dataset.confirmInput;
    const emailSelector = container.dataset.emailInput;
    const scope = document;
    const passwordInput = passwordSelector ? scope.querySelector(passwordSelector) : null;
    const confirmInput = confirmSelector ? scope.querySelector(confirmSelector) : null;
    const emailInput = emailSelector ? scope.querySelector(emailSelector) : null;
    if (passwordSelector && !passwordInput) {
      warnOnce('UI_EL_MISSING', `Missing password input: ${passwordSelector}`, { module: 'password-hints' });
    }
    if (confirmSelector && !confirmInput) {
      warnOnce('UI_EL_MISSING', `Missing confirm input: ${confirmSelector}`, { module: 'password-hints' });
    }
    if (emailSelector && !emailInput) {
      warnOnce('UI_EL_MISSING', `Missing email input: ${emailSelector}`, { module: 'password-hints' });
    }
    const minLength = Number.parseInt(container.dataset.minLength || '12', 10);
    const items = container.querySelectorAll('[data-rule]');

    const setState = (item, state) => {
      item.classList.remove('is-valid', 'is-invalid');
      if (state === 'valid') {item.classList.add('is-valid');}
      if (state === 'invalid') {item.classList.add('is-invalid');}
    };

    const evaluate = () => {
      const password = passwordInput?.value ?? '';
      const confirm = confirmInput?.value ?? '';
      const email = emailInput?.value ?? '';
      const hasValue = password.length > 0 || confirm.length > 0;

      items.forEach((item) => {
        const rule = item.dataset.rule;
        if (!rule) {return;}
        if (!hasValue) {
          setState(item, 'neutral');
          return;
        }
        if (rule === 'match') {
          if (password === '' || confirm === '') {
            setState(item, 'neutral');
            return;
          }
          setState(item, password === confirm ? 'valid' : 'invalid');
          return;
        }
        const check = rules[rule];
        if (!check) {return;}
        const ok = check(password, minLength, email, confirm);
        setState(item, ok ? 'valid' : 'invalid');
      });
    };

    if (passwordInput) {
      passwordInput.addEventListener('input', evaluate);
      cleanupFns.push(() => passwordInput.removeEventListener('input', evaluate));
    }
    if (confirmInput) {
      confirmInput.addEventListener('input', evaluate);
      cleanupFns.push(() => confirmInput.removeEventListener('input', evaluate));
    }
    if (emailInput) {
      emailInput.addEventListener('input', evaluate);
      cleanupFns.push(() => emailInput.removeEventListener('input', evaluate));
    }
    evaluate();
    container.dataset.passwordHintsBound = '1';
    cleanupFns.push(() => {
      delete container.dataset.passwordHintsBound;
    });
  });

  const destroy = () => {
    cleanupFns.forEach((cleanup) => cleanup());
  };

  return { destroy };
}
