/* ============================================================
   form.js — Estimate form validation + submission
   Real-time validation, phone formatting, reCAPTCHA v3 hook
   ============================================================ */

(function () {
  'use strict';

  const PHONE   = /^\(?\d{3}\)?[\s.\-]?\d{3}[\s.\-]?\d{4}$/;
  const EMAIL   = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  const RECAPTCHA_SITE_KEY = '6LdqrB8rAAAAAOrBCYmtk43IzemkiK_Fb2EYU5q2';

  /* --- Helpers -------------------------------------------- */
  function field(el) {
    return el.closest('.form-field');
  }

  function setValid(el) {
    const f = field(el);
    if (!f) return;
    f.classList.remove('has-error');
    el.classList.add('valid');
    el.classList.remove('invalid');
  }

  function setInvalid(el, msg) {
    const f = field(el);
    if (!f) return;
    f.classList.add('has-error');
    el.classList.add('invalid');
    el.classList.remove('valid');
    const errEl = f.querySelector('.err-msg');
    if (errEl && msg) errEl.textContent = msg;
  }

  function clearState(el) {
    const f = field(el);
    if (!f) return;
    f.classList.remove('has-error');
    el.classList.remove('valid', 'invalid');
  }

  /* --- Phone formatter ------------------------------------ */
  function formatPhone(raw) {
    const digits = raw.replace(/\D/g, '').slice(0, 10);
    if (digits.length < 4)  return digits;
    if (digits.length < 7)  return '(' + digits.slice(0,3) + ') ' + digits.slice(3);
    return '(' + digits.slice(0,3) + ') ' + digits.slice(3,6) + '-' + digits.slice(6);
  }

  /* --- Validators ----------------------------------------- */
  function validateRequired(el) {
    if (!el.value.trim()) {
      setInvalid(el, 'This field is required.');
      return false;
    }
    setValid(el);
    return true;
  }

  function validateEmail(el) {
    if (!el.value.trim()) {
      setInvalid(el, 'Email address is required.');
      return false;
    }
    if (!EMAIL.test(el.value.trim())) {
      setInvalid(el, 'Please enter a valid email address.');
      return false;
    }
    setValid(el);
    return true;
  }

  function validatePhone(el) {
    const val = el.value.replace(/\D/g, '');
    if (!val) {
      setInvalid(el, 'Phone number is required.');
      return false;
    }
    if (val.length !== 10) {
      setInvalid(el, 'Please enter a 10-digit phone number.');
      return false;
    }
    setValid(el);
    return true;
  }

  /* --- reCAPTCHA v3 token --------------------------------- */
  function getRecaptchaToken(action) {
    return new Promise((resolve) => {
      if (typeof grecaptcha === 'undefined') {
        resolve('');
        return;
      }
      grecaptcha.ready(() => {
        grecaptcha.execute(RECAPTCHA_SITE_KEY, { action }).then(resolve);
      });
    });
  }

  /* --- Form handler --------------------------------------- */
  function initForm(form) {
    const nameEl    = form.querySelector('#name');
    const emailEl   = form.querySelector('#email');
    const phoneEl   = form.querySelector('#phone');
    const addrEl    = form.querySelector('#address');
    const serviceEl = form.querySelector('#service');
    const msgEl     = form.querySelector('#message');
    const submit    = form.querySelector('[type="submit"]');
    const status    = form.querySelector('.form-status');

    if (!submit) return;

    /* Phone real-time format */
    if (phoneEl) {
      phoneEl.addEventListener('input', () => {
        const pos = phoneEl.selectionStart;
        const prev = phoneEl.value;
        phoneEl.value = formatPhone(prev);
        /* restore cursor roughly */
        const diff = phoneEl.value.length - prev.length;
        try { phoneEl.setSelectionRange(pos + diff, pos + diff); } catch (_) {}
      });

      phoneEl.addEventListener('blur', () => validatePhone(phoneEl));
    }

    /* Blur-time validation for other fields */
    if (nameEl)    nameEl.addEventListener('blur',  () => validateRequired(nameEl));
    if (emailEl)   emailEl.addEventListener('blur', () => validateEmail(emailEl));
    if (addrEl)    addrEl.addEventListener('blur',  () => validateRequired(addrEl));
    if (serviceEl) serviceEl.addEventListener('change', () => validateRequired(serviceEl));

    /* Submit */
    form.addEventListener('submit', async (e) => {
      e.preventDefault();

      const checks = [
        nameEl    ? validateRequired(nameEl)  : true,
        emailEl   ? validateEmail(emailEl)    : true,
        phoneEl   ? validatePhone(phoneEl)    : true,
        addrEl    ? validateRequired(addrEl)  : true,
        serviceEl ? validateRequired(serviceEl) : true,
      ];

      if (checks.includes(false)) {
        const firstErr = form.querySelector('.invalid');
        if (firstErr) firstErr.focus();
        return;
      }

      const origText = submit.textContent;
      submit.disabled = true;
      submit.textContent = 'Sending...';
      if (status) { status.className = 'form-status'; status.textContent = ''; }

      const token = await getRecaptchaToken('estimate_form');

      const payload = {
        name:    nameEl    ? nameEl.value.trim()    : '',
        email:   emailEl   ? emailEl.value.trim()   : '',
        phone:   phoneEl   ? phoneEl.value.trim()   : '',
        address: addrEl    ? addrEl.value.trim()    : '',
        service: serviceEl ? serviceEl.value        : '',
        message: msgEl     ? msgEl.value.trim()     : '',
        token,
      };

      try {
        const res = await fetch('/api/estimate', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(payload),
        });

        if (!status) { submit.disabled = false; submit.textContent = origText; return; }

        if (res.ok) {
          status.className = 'form-status form-status--success';
          status.textContent = 'Thank you! We will get back to you within 1 business hour.';
          form.reset();
          form.querySelectorAll('input, textarea, select').forEach(clearState);
        } else {
          throw new Error(res.status);
        }
      } catch (_) {
        if (status) {
          status.className = 'form-status form-status--error';
          status.textContent = 'Something went wrong. Please call us directly at (716) 602-1429.';
        }
      } finally {
        submit.disabled = false;
        submit.textContent = origText;
      }
    });
  }

  function boot() {
    document.querySelectorAll('.estimate-form').forEach(initForm);
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', boot);
  } else {
    boot();
  }
})();
