/* ==========================================================================
   Niwa Chatbot -- Form Handler
   ---------------------------------------------------------------------------
   Email capture, phone capture, and standard message form management.
   No jQuery. All DOM operations use vanilla JS.

   NAMESPACE: window.Niwa.FormHandler
   ========================================================================== */

window.Niwa = window.Niwa || {};

window.Niwa.FormHandler = (function () {
  'use strict';

  /* -- Helpers ------------------------------------------------------------ */

  function _renderer() {
    return window.Niwa && window.Niwa.MessageRenderer;
  }

  function _utils() {
    return window.Niwa && window.Niwa.Utils;
  }

  function _getFormContainer() {
    return document.querySelector('.niwa-morph__input')
      || document.querySelector('.niwa-center__input');
  }

  // Saved references to native input children (textarea + send button)
  // detached while a capture form is active. Keyed by formContainer element
  // so morph and center can each maintain their own set independently.
  var _detachedNativeMap = [];

  /**
   * Detach native chat input children (textarea + send button) from the DOM
   * and save them so they can be re-inserted by _reattachNativeChildren().
   * Uses an in-memory map keyed by the container element — avoids any CSS
   * specificity battle that would occur with display:none.
   */
  function _detachNativeChildren(formContainer) {
    if (!formContainer) return;
    // Remove any existing entry for this container.
    _detachedNativeMap = _detachedNativeMap.filter(function (e) { return e.container !== formContainer; });

    var children = Array.prototype.slice.call(formContainer.children);
    var saved = [];
    children.forEach(function (el) {
      if (el.classList && el.classList.contains('niwa-form')) return;
      formContainer.removeChild(el);
      saved.push(el);
    });
    if (saved.length) {
      _detachedNativeMap.push({ container: formContainer, nodes: saved });
    }
  }

  /**
   * Re-insert native children previously detached by _detachNativeChildren()
   * at the beginning of the container (before any leftover capture form).
   */
  function _reattachNativeChildren(formContainer) {
    if (!formContainer) return;
    var entry = null;
    _detachedNativeMap = _detachedNativeMap.filter(function (e) {
      if (e.container === formContainer) { entry = e; return false; }
      return true;
    });
    if (!entry) return;
    var firstChild = formContainer.firstChild;
    entry.nodes.forEach(function (el) {
      formContainer.insertBefore(el, firstChild);
    });
  }

  /**
   * Remove any existing capture form (.niwa-form) so successive capture
   * renders don't stack inside the input container.
   */
  function _removeCaptureForms(formContainer) {
    if (!formContainer) return;
    var existing = formContainer.querySelectorAll('.niwa-form');
    for (var i = 0; i < existing.length; i++) {
      if (existing[i].parentNode) {
        existing[i].parentNode.removeChild(existing[i]);
      }
    }
  }

  function _scrollToBottom() {
    var bodyEl = document.querySelector('.niwa-morph__body')
      || document.querySelector('.niwa-center__body');
    if (bodyEl && window.Niwa && window.Niwa.ScrollBehavior) {
      window.Niwa.ScrollBehavior.scrollToBottom(bodyEl);
    }
  }

  function _extractAjaxError(response, fallback) {
    var u = _utils();
    if (u) return u.extractAjaxErrorMessage(response, fallback);
    return fallback || '';
  }

  /* -- Show Form Dispatch ------------------------------------------------- */

  function showForm(type, data) {
    switch (type) {
      case 'email':
        showEmailForm(data);
        break;
      case 'phone':
        showPhoneForm(data);
        break;
      case 'standard':
        showStandardForm();
        break;
      default:
        showStandardForm();
    }
  }

  /* -- Email Form --------------------------------------------------------- */

  /**
   * Detect which chat input context hosts the capture form so we can
   * apply matching modern classes (niwa-morph__* vs niwa-center__*).
   * Falls back to morph (used by shortcode too).
   */
  function _detectInputContext(parentEl) {
    if (parentEl && parentEl.classList && parentEl.classList.contains('niwa-center__input')) {
      return 'center';
    }
    return 'morph';
  }

  function _sendArrowSvg() {
    return ''
      + '<svg width="32" height="32" viewBox="0 0 32 32" fill="none" aria-hidden="true">'
      + '<path d="M16 22L16 10M16 10L11 15M16 10L21 15" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/>'
      + '</svg>';
  }

  function _createHoneypot() {
    var hp = document.createElement('input');
    hp.type = 'text';
    hp.name = 'website';
    hp.value = '';
    hp.style.cssText = 'display:none !important; position:absolute; left:-9999px;';
    hp.tabIndex = -1;
    hp.autocomplete = 'off';
    return hp;
  }

  function _createTimestamp() {
    var ts = document.createElement('input');
    ts.type = 'hidden';
    ts.name = '_niwa_t';
    ts.value = String(Math.floor(Date.now() / 1000));
    return ts;
  }

  function _createEmailFormHtml() {
    var labels = (window.NiwaAI && window.NiwaAI.labels) || {};
    var ctx = _detectInputContext(_getFormContainer());
    var inputNativeCls = ctx === 'center' ? 'niwa-center__textarea' : 'niwa-morph__textarea';
    var sendNativeCls = ctx === 'center' ? 'niwa-center__send' : 'niwa-morph__send';
    var sendDisabledCls = sendNativeCls + '--disabled';

    var container = document.createElement('form');
    container.className = 'niwa-form niwa-form--email niwa-form--inline';
    container.setAttribute('novalidate', 'novalidate');

    // Email input — styled as flat chat textarea
    var emailInput = document.createElement('input');
    emailInput.type = 'email';
    emailInput.name = 'email';
    emailInput.className = inputNativeCls + ' niwa-form__input';
    emailInput.placeholder = labels.email_placeholder || 'your.email@example.com';
    emailInput.setAttribute('aria-label', labels.email_label || 'Email');
    emailInput.autocomplete = 'email';
    emailInput.required = true;
    container.appendChild(emailInput);

    // Anti-spam fields
    container.appendChild(_createHoneypot());
    container.appendChild(_createTimestamp());

    // Submit button — matches modern send (32px dark circle + up-arrow svg)
    var btn = document.createElement('button');
    btn.type = 'submit';
    btn.className = sendNativeCls + ' ' + sendDisabledCls + ' niwa-form__submit';
    btn.setAttribute('aria-label', labels.email_continue || labels.send || 'Send');
    btn.innerHTML = _sendArrowSvg();
    container.appendChild(btn);

    // Inline error (absolute positioned under input)
    var err = document.createElement('div');
    err.className = 'niwa-form__error';
    err.style.display = 'none';
    container.appendChild(err);

    return container;
  }

  function _isCbEmailHuntActive() {
    var frontend = window.NiwaAIFrontend || null;
    return !!(frontend && frontend.cb && typeof frontend.cb.isEmailHuntActive === 'function' && frontend.cb.isEmailHuntActive());
  }

  function _isEmailStartChatCacherActive() {
    // Active when the setting is on AND user has not yet unlocked chat in this session.
    if (!window.NiwaAI || !window.NiwaAI.email_start_chat_cacher_enabled) return false;
    try {
      if (sessionStorage.getItem('niwa_validated_email')) return false;
    } catch (e) { /* ignore */ }
    return true;
  }

  function _contactSource() {
    if (_isCbEmailHuntActive()) return 'cb_code_email_hunt';
    if (_isEmailStartChatCacherActive()) return 'email_start_chat_cacher';
    return 'chat';
  }

  function showEmailForm(promptText, options) {
    options = options || {};

    // Guard: check for existing validated email
    try {
      var globalEmail = sessionStorage.getItem('niwa_validated_email');
      if (globalEmail && !options.force) {
        showStandardForm();
        return;
      }
    } catch (e) { /* ignore */ }

    var renderer = _renderer();
    var labels = (window.NiwaAI && window.NiwaAI.labels) || {};

    // Show email prompt as chat message (if promptText provided)
    if (promptText !== false && renderer) {
      var prompt = promptText
        || labels.email_prompt_no_name
        || labels.email_prompt
        || 'Please enter your email so we can chat :)';
      var addOpts = {};
      if (options.messageSource) {
        addOpts.source = options.messageSource;
      }
      renderer.addMessage(prompt, 'bot', addOpts);
    }

    // Replace form area — hide native textarea/send (do NOT remove, so we can
    // restore them later) and append the capture form alongside.
    var formContainer = _getFormContainer();
    if (!formContainer) return;

    var form = _createEmailFormHtml();
    _removeCaptureForms(formContainer);
    _detachNativeChildren(formContainer);
    formContainer.appendChild(form);
    _setupEmailFormHandlers(form);

    // Focus
    setTimeout(function () {
      var inp = form.querySelector('.niwa-form__input');
      if (inp) inp.focus();
    }, 150);
  }

  function _setupEmailFormHandlers(formEl) {
    var emailInput = formEl.querySelector('input[name="email"]');
    var submitBtn = formEl.querySelector('.niwa-form__submit');
    var errorDiv = formEl.querySelector('.niwa-form__error');
    var lastSubmit = 0;

    // Sync send-button disabled look with input emptiness (mimics chat send).
    function _syncSubmitState() {
      if (!submitBtn) return;
      var empty = !emailInput || emailInput.value.trim() === '';
      // Handle both morph__send--disabled and center__send--disabled variants.
      submitBtn.classList.toggle('niwa-morph__send--disabled', empty);
      submitBtn.classList.toggle('niwa-center__send--disabled', empty);
    }
    _syncSubmitState();

    function submitEmail() {
      var now = Date.now();
      if (now - lastSubmit < 1000) return;
      lastSubmit = now;

      var email = emailInput ? emailInput.value.trim() : '';
      var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

      // Anti-spam: honeypot
      var hp = formEl.querySelector('input[name="website"]');
      if (hp && hp.value !== '') return;

      if (!emailRegex.test(email)) {
        var labels = (window.NiwaAI && window.NiwaAI.labels) || {};
        var renderer = _renderer();
        if (renderer) {
          renderer.addMessage(labels.email_invalid || 'Please enter a valid email address', 'bot');
        }
        if (emailInput) emailInput.value = '';
        return;
      }

      // Clear input
      if (emailInput) emailInput.value = '';

      var ajaxUrl = window.NiwaAI && window.NiwaAI.ajax;
      var ajaxNonce = window.NiwaAI && window.NiwaAI.nonce;
      if (!ajaxUrl || !ajaxNonce) return;

      var tsField = formEl.querySelector('input[name="_niwa_t"]');
      var hpField = formEl.querySelector('input[name="website"]');

      var fd = new FormData();
      fd.append('action', 'niwa_ai_save_contact');
      fd.append('nonce', ajaxNonce);
      fd.append('email', email);
      fd.append('name', '');
      fd.append('source', _contactSource());
      fd.append('website', hpField ? hpField.value : '');
      fd.append('_niwa_t', tsField ? tsField.value : '');

      fetch(ajaxUrl, { method: 'POST', body: fd })
        .then(function (r) { return r.json(); })
        .then(function (response) {
          var renderer = _renderer();
          if (response.success) {
            // Save email globally
            try {
              sessionStorage.setItem('niwa_validated_email', email);
            } catch (e) { /* ignore */ }

            var cbConsumed = false;
            if (window.NiwaAIFrontend && window.NiwaAIFrontend.cb && typeof window.NiwaAIFrontend.cb.onEmailCaptured === 'function') {
              cbConsumed = !!window.NiwaAIFrontend.cb.onEmailCaptured(email);
            }

            if (cbConsumed) {
              showStandardForm();
              setTimeout(_scrollToBottom, 150);
              return;
            }

            var labels = (window.NiwaAI && window.NiwaAI.labels) || {};
            if (renderer) {
              renderer.addMessage(labels.email_connected || 'Thank you, now we are connected! What can I help you with?', 'bot', { forceNewGroup: true });
            }
            setTimeout(_scrollToBottom, 150);

            // Check if phone capture follows
            var phoneCaptureEnabled = !!(window.NiwaAI && window.NiwaAI.phone_capture_enabled);
            var phoneMode = (window.NiwaAI && window.NiwaAI.phone_capture_mode) || 'email_phone';
            if (phoneCaptureEnabled && phoneMode === 'email_phone') {
              showPhoneForm();
            } else {
              showStandardForm();
            }
          } else {
            var labels2 = (window.NiwaAI && window.NiwaAI.labels) || {};
            var errMsg = _extractAjaxError(response, labels2.email_invalid || 'Please enter a valid email address');
            if (renderer) renderer.addMessage(errMsg, 'bot');
            if (errorDiv) {
              errorDiv.textContent = errMsg;
              errorDiv.style.display = '';
            }
          }
        })
        .catch(function () {
          var renderer = _renderer();
          if (renderer) renderer.addMessage('Connection error. Please try again.', 'bot');
          if (errorDiv) {
            errorDiv.textContent = 'Connection error';
            errorDiv.style.display = '';
          }
        });
    }

    // Event handlers
    if (submitBtn) {
      submitBtn.addEventListener('click', function (e) {
        e.preventDefault();
        submitEmail();
      });
    }

    if (emailInput) {
      emailInput.addEventListener('keydown', function (e) {
        if (e.key === 'Enter') {
          e.preventDefault();
          e.stopPropagation();
          submitEmail();
        }
      });

      emailInput.addEventListener('input', function () {
        if (errorDiv) errorDiv.style.display = 'none';
        _syncSubmitState();
      });
    }

    // Form submit prevention
    formEl.addEventListener('submit', function (e) {
      e.preventDefault();
      e.stopPropagation();
      submitEmail();
    });
  }

  /* -- Phone Form --------------------------------------------------------- */

  function _createPhoneFormHtml() {
    var labels = (window.NiwaAI && window.NiwaAI.labels) || {};
    var ctx = _detectInputContext(_getFormContainer());
    var inputNativeCls = ctx === 'center' ? 'niwa-center__textarea' : 'niwa-morph__textarea';
    var sendNativeCls = ctx === 'center' ? 'niwa-center__send' : 'niwa-morph__send';
    var sendDisabledCls = sendNativeCls + '--disabled';

    var container = document.createElement('form');
    container.className = 'niwa-form niwa-form--phone niwa-form--inline';
    container.setAttribute('novalidate', 'novalidate');

    // Phone input — styled as flat chat textarea
    var phoneInput = document.createElement('input');
    phoneInput.type = 'tel';
    phoneInput.name = 'phone';
    phoneInput.className = inputNativeCls + ' niwa-form__input';
    phoneInput.placeholder = labels.phone_placeholder || '+1 555 123 4567';
    phoneInput.setAttribute('aria-label', labels.phone_label || 'Phone');
    phoneInput.autocomplete = 'tel';
    phoneInput.required = true;
    container.appendChild(phoneInput);

    // Anti-spam fields
    container.appendChild(_createHoneypot());
    container.appendChild(_createTimestamp());

    // Submit button — matches modern send
    var btn = document.createElement('button');
    btn.type = 'submit';
    btn.className = sendNativeCls + ' ' + sendDisabledCls + ' niwa-form__submit';
    btn.setAttribute('aria-label', labels.email_continue || labels.send || 'Send');
    btn.innerHTML = _sendArrowSvg();
    container.appendChild(btn);

    // Inline error
    var err = document.createElement('div');
    err.className = 'niwa-form__error';
    err.style.display = 'none';
    container.appendChild(err);

    return container;
  }

  function showPhoneForm(promptText) {
    if (!(window.NiwaAI && window.NiwaAI.phone_capture_enabled)) {
      showStandardForm();
      return;
    }

    var renderer = _renderer();
    var labels = (window.NiwaAI && window.NiwaAI.labels) || {};

    // Show phone prompt (unless skipPrompt)
    if (promptText !== false && renderer) {
      var prompt = promptText
        || labels.phone_prompt_no_name
        || labels.phone_prompt
        || 'Can you please give me your phone number?';
      renderer.addMessage(prompt, 'bot');
    }

    var formContainer = _getFormContainer();
    if (!formContainer) return;

    var form = _createPhoneFormHtml();
    _removeCaptureForms(formContainer);
    _detachNativeChildren(formContainer);
    formContainer.appendChild(form);
    _setupPhoneFormHandlers(form);

    setTimeout(function () {
      var inp = form.querySelector('.niwa-form__input');
      if (inp) inp.focus();
    }, 150);
  }

  function _setupPhoneFormHandlers(formEl) {
    var phoneInput = formEl.querySelector('input[name="phone"]');
    var submitBtn = formEl.querySelector('.niwa-form__submit');
    var errorDiv = formEl.querySelector('.niwa-form__error');
    var lastSubmit = 0;

    function _syncSubmitState() {
      if (!submitBtn) return;
      var empty = !phoneInput || phoneInput.value.trim() === '';
      submitBtn.classList.toggle('niwa-morph__send--disabled', empty);
      submitBtn.classList.toggle('niwa-center__send--disabled', empty);
    }
    _syncSubmitState();

    function submitPhone() {
      var now = Date.now();
      if (now - lastSubmit < 1000) return;
      lastSubmit = now;

      var phone = phoneInput ? phoneInput.value.trim() : '';
      var phoneRegex = /^[\+]?[(]?[0-9]{1,4}[)]?[-\s\.]?[(]?[0-9]{1,4}[)]?[-\s\.]?[0-9]{1,9}$/;

      // Anti-spam: honeypot
      var hp = formEl.querySelector('input[name="website"]');
      if (hp && hp.value !== '') return;

      if (!phoneRegex.test(phone)) {
        var labels = (window.NiwaAI && window.NiwaAI.labels) || {};
        var renderer = _renderer();
        if (renderer) {
          renderer.addMessage(labels.phone_invalid || 'Please enter a valid phone number', 'bot');
        }
        if (phoneInput) phoneInput.value = '';
        return;
      }

      var ajaxUrl = window.NiwaAI && window.NiwaAI.ajax;
      var ajaxNonce = window.NiwaAI && window.NiwaAI.nonce;
      if (!ajaxUrl || !ajaxNonce) return;

      var email = '';
      try { email = sessionStorage.getItem('niwa_validated_email') || ''; } catch (e) { /* ignore */ }

      var tsField = formEl.querySelector('input[name="_niwa_t"]');
      var hpField = formEl.querySelector('input[name="website"]');

      var fd = new FormData();
      fd.append('action', 'niwa_ai_save_contact');
      fd.append('nonce', ajaxNonce);
      fd.append('email', email);
      fd.append('name', '');
      fd.append('phone', phone);
      fd.append('website', hpField ? hpField.value : '');
      fd.append('_niwa_t', tsField ? tsField.value : '');

      fetch(ajaxUrl, { method: 'POST', body: fd })
        .then(function (r) { return r.json(); })
        .then(function (response) {
          var renderer = _renderer();
          if (response.success) {
            var cbConsumed = false;
            if (window.NiwaAIFrontend && window.NiwaAIFrontend.cb && typeof window.NiwaAIFrontend.cb.onPhoneCaptured === 'function') {
              cbConsumed = !!window.NiwaAIFrontend.cb.onPhoneCaptured(phone);
            }

            if (cbConsumed) {
              showStandardForm();
              setTimeout(_scrollToBottom, 150);
              return;
            }

            var labels = (window.NiwaAI && window.NiwaAI.labels) || {};
            if (renderer) {
              renderer.addMessage(labels.phone_connected || 'Thank you! How can I help you?', 'bot', { forceNewGroup: true });
            }
            setTimeout(_scrollToBottom, 150);
            showStandardForm();
          } else {
            var labels2 = (window.NiwaAI && window.NiwaAI.labels) || {};
            if (renderer) {
              renderer.addMessage(_extractAjaxError(response, labels2.phone_invalid || 'Please enter a valid phone number'), 'bot');
            }
          }
        })
        .catch(function () {
          var renderer = _renderer();
          if (renderer) renderer.addMessage('Connection error. Please try again.', 'bot');
        });
    }

    if (submitBtn) {
      submitBtn.addEventListener('click', function (e) {
        e.preventDefault();
        submitPhone();
      });
    }

    if (phoneInput) {
      phoneInput.addEventListener('keydown', function (e) {
        if (e.key === 'Enter') {
          e.preventDefault();
          e.stopPropagation();
          submitPhone();
        }
      });

      phoneInput.addEventListener('input', function () {
        if (errorDiv) errorDiv.style.display = 'none';
        _syncSubmitState();
      });
    }

    formEl.addEventListener('submit', function (e) {
      e.preventDefault();
      e.stopPropagation();
      submitPhone();
    });
  }

  /* -- Standard Form (restore textarea) ----------------------------------- */

  function showStandardForm() {
    // The standard form is the built-in textarea that already exists
    // in the morph/center HTML. Remove any capture form and restore
    // native input children that were hidden by showEmailForm/showPhoneForm.
    var formContainer = _getFormContainer();
    if (!formContainer) return;

    _removeCaptureForms(formContainer);
    _reattachNativeChildren(formContainer);

    var textarea = formContainer.querySelector('textarea');
    if (textarea) {
      setTimeout(function () { textarea.focus(); }, 150);
    }
  }

  /* -- Public API --------------------------------------------------------- */

  return {
    showForm: showForm,
    showEmailForm: showEmailForm,
    showPhoneForm: showPhoneForm,
    showStandardForm: showStandardForm
  };
})();
