/*
 * Progressive-enhancement JS for the /install setup wizard.
 *
 * Without this file (or with JS disabled), install/form.blade.php degrades to
 * a single scrollable form — every step panel is visible by default in plain
 * document flow, the step dots and Back/Next controls stay hidden (see
 * install.css: `.js-enabled` gates are the only thing that switches to the
 * stepped view), and the final "Install" button is a normal type=submit
 * button that posts the whole form in one request regardless.
 *
 * With this file, we add a `.js-enabled` class, wire up step navigation,
 * the AJAX DB-connection test, lightweight client-side validation hints, and
 * a spinner overlay shown right before the (still perfectly normal, full
 * page POST) install submit navigates away.
 */
(function () {
  'use strict';

  var wizard = document.querySelector('[data-install-wizard]');
  if (!wizard) {
    return;
  }

  var html = document.documentElement;
  html.classList.add('js-enabled');

  var panels = Array.prototype.slice.call(wizard.querySelectorAll('.step-panel'));
  var dots = Array.prototype.slice.call(wizard.querySelectorAll('.step-dot'));
  var form = wizard.closest('form') || document.getElementById('install-form');
  var card = document.querySelector('.installer-card');

  var STEP_WELCOME = 0;
  var STEP_REQUIREMENTS = 1;
  var STEP_DATABASE = 2;
  var STEP_SITE_ADMIN = 3;
  var STEP_REVIEW = 4;

  var preflightOk = wizard.getAttribute('data-preflight-ok') === '1';
  var dbTestPassed = false;

  var startStep = parseInt(wizard.getAttribute('data-start-step'), 10);
  if (isNaN(startStep) || startStep < 0 || startStep >= panels.length) {
    startStep = 0;
  }

  var current = 0;

  function showStep(index) {
    if (index < 0 || index >= panels.length) {
      return;
    }
    current = index;

    panels.forEach(function (panel, i) {
      panel.classList.toggle('is-active', i === index);
    });

    dots.forEach(function (dot, i) {
      dot.classList.toggle('is-active', i === index);
      dot.classList.toggle('is-complete', i < index);
      if (i === index) {
        dot.setAttribute('aria-current', 'step');
      } else {
        dot.removeAttribute('aria-current');
      }
    });

    if (index === STEP_REVIEW) {
      updateReviewSummary();
    }

    if (card) {
      card.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }
  }

  function fieldByName(name) {
    return form ? form.elements.namedItem(name) : document.getElementsByName(name)[0];
  }

  function validatePanel(index) {
    var panel = panels[index];
    if (!panel) {
      return true;
    }
    var invalid = Array.prototype.slice
      .call(panel.querySelectorAll('input[required]'))
      .find(function (el) {
        return !el.checkValidity();
      });
    if (invalid) {
      invalid.reportValidity();
      invalid.focus();
      return false;
    }
    return true;
  }

  function goNext() {
    if (!validatePanel(current)) {
      return;
    }

    if (current === STEP_REQUIREMENTS && !preflightOk) {
      return;
    }

    if (current === STEP_DATABASE && !dbTestPassed) {
      var hint = document.getElementById('db-test-required-hint');
      if (hint) {
        hint.classList.add('is-visible');
      }
      var testBtn = document.getElementById('db-test-btn');
      if (testBtn) {
        testBtn.focus();
      }
      return;
    }

    showStep(current + 1);
  }

  function goBack() {
    showStep(current - 1);
  }

  wizard.querySelectorAll('[data-goto-next]').forEach(function (btn) {
    btn.addEventListener('click', goNext);
  });
  wizard.querySelectorAll('[data-goto-back]').forEach(function (btn) {
    btn.addEventListener('click', goBack);
  });

  dots.forEach(function (dot, i) {
    dot.addEventListener('click', function (e) {
      // Only allow jumping to a step that's already been reached, or one
      // step forward (mirrors typical WordPress-style installers — you
      // can freely revisit earlier steps, but can't leapfrog validation).
      if (i <= current) {
        e.preventDefault();
        showStep(i);
      } else {
        e.preventDefault();
      }
    });
  });

  /* ---------------------------------------------------------------- */
  /* Database "Test connection" AJAX call                              */
  /* ---------------------------------------------------------------- */

  var testBtn = document.getElementById('db-test-btn');
  var resultBox = document.getElementById('db-test-result');
  var dbFieldNames = ['db_host', 'db_port', 'db_database', 'db_username', 'db_password'];

  function setDbTestResult(ok, message) {
    if (!resultBox) {
      return;
    }
    resultBox.classList.add('is-visible');
    resultBox.classList.toggle('is-ok', ok);
    resultBox.classList.toggle('is-fail', !ok);
    resultBox.textContent = (ok ? '✓ ' : '✗ ') + message;
  }

  function clearDbTestResult() {
    dbTestPassed = false;
    if (resultBox) {
      resultBox.classList.remove('is-visible', 'is-ok', 'is-fail');
      resultBox.textContent = '';
    }
    var hint = document.getElementById('db-test-required-hint');
    if (hint) {
      hint.classList.remove('is-visible');
    }
  }

  dbFieldNames.forEach(function (name) {
    var el = fieldByName(name);
    if (el) {
      el.addEventListener('input', clearDbTestResult);
    }
  });

  if (testBtn) {
    testBtn.addEventListener('click', function () {
      var payload = {};
      dbFieldNames.forEach(function (name) {
        var el = fieldByName(name);
        payload[name] = el ? el.value : '';
      });

      var csrfMeta = document.querySelector('meta[name="csrf-token"]');
      var csrfToken = csrfMeta ? csrfMeta.getAttribute('content') : '';
      var endpoint = wizard.getAttribute('data-test-db-url');

      testBtn.disabled = true;
      var originalLabel = testBtn.textContent;
      testBtn.textContent = 'Testing…';
      clearDbTestResult();

      fetch(endpoint, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Accept: 'application/json',
          'X-CSRF-TOKEN': csrfToken,
        },
        body: JSON.stringify(payload),
      })
        .then(function (res) {
          return res
            .json()
            .catch(function () {
              return { ok: false, message: 'Unexpected server response (HTTP ' + res.status + ').' };
            });
        })
        .then(function (json) {
          dbTestPassed = !!json.ok;
          setDbTestResult(dbTestPassed, json.message || (dbTestPassed ? 'Connected successfully.' : 'Connection failed.'));
        })
        .catch(function () {
          dbTestPassed = false;
          setDbTestResult(false, 'Could not reach the server to test the connection. Check your network and try again.');
        })
        .finally(function () {
          testBtn.disabled = false;
          testBtn.textContent = originalLabel;
        });
    });
  }

  /* ---------------------------------------------------------------- */
  /* Password strength hint + confirm-match check                      */
  /* ---------------------------------------------------------------- */

  var pwField = fieldByName('admin_password');
  var pwConfirmField = fieldByName('admin_password_confirmation');
  var pwStrengthBox = document.getElementById('pw-strength');
  var pwMismatchBox = document.getElementById('pw-mismatch');

  function estimateStrength(pw) {
    if (!pw) {
      return null;
    }
    var classes = 0;
    if (/[a-z]/.test(pw)) classes++;
    if (/[A-Z]/.test(pw)) classes++;
    if (/[0-9]/.test(pw)) classes++;
    if (/[^A-Za-z0-9]/.test(pw)) classes++;

    if (pw.length >= 12 && classes >= 3) {
      return { label: 'Strong password', css: 'pw-strong' };
    }
    if (pw.length >= 8 && classes >= 2) {
      return { label: 'Medium strength — consider mixing in numbers/symbols', css: 'pw-medium' };
    }
    return { label: 'Weak — use 8+ characters with a mix of letters, numbers, symbols', css: 'pw-weak' };
  }

  function checkPasswordMatch() {
    if (!pwField || !pwConfirmField || !pwMismatchBox) {
      return;
    }
    if (pwConfirmField.value && pwConfirmField.value !== pwField.value) {
      pwMismatchBox.textContent = 'Passwords do not match.';
      pwConfirmField.setCustomValidity('Passwords do not match.');
    } else {
      pwMismatchBox.textContent = '';
      pwConfirmField.setCustomValidity('');
    }
  }

  if (pwField && pwStrengthBox) {
    pwField.addEventListener('input', function () {
      var s = estimateStrength(pwField.value);
      pwStrengthBox.className = 'pw-strength' + (s ? ' ' + s.css : '');
      pwStrengthBox.textContent = s ? s.label : '';
      checkPasswordMatch();
    });
  }
  if (pwConfirmField) {
    pwConfirmField.addEventListener('input', checkPasswordMatch);
  }

  /* ---------------------------------------------------------------- */
  /* Review step summary                                               */
  /* ---------------------------------------------------------------- */

  function setReviewText(id, value) {
    var el = document.getElementById(id);
    if (el) {
      el.textContent = value || '—';
    }
  }

  function updateReviewSummary() {
    setReviewText('review_app_name', valueOf('app_name'));
    setReviewText('review_app_url', valueOf('app_url'));
    setReviewText('review_site_count', valueOf('site_count'));
    setReviewText('review_db_host', valueOf('db_host') + (valueOf('db_port') ? ':' + valueOf('db_port') : ''));
    setReviewText('review_db_database', valueOf('db_database'));
    setReviewText('review_db_username', valueOf('db_username'));
    setReviewText('review_admin_name', valueOf('admin_name'));
    setReviewText('review_admin_email', valueOf('admin_email'));
  }

  function valueOf(name) {
    var el = fieldByName(name);
    return el ? el.value : '';
  }

  /* ---------------------------------------------------------------- */
  /* Final submit — show the "Installing…" overlay, then let the       */
  /* browser continue its perfectly normal full-page POST.             */
  /* ---------------------------------------------------------------- */

  if (form) {
    form.addEventListener('submit', function (e) {
      if (!validatePanel(STEP_REVIEW)) {
        e.preventDefault();
        return;
      }
      if (card) {
        card.classList.add('is-installing');
      }
      // Deliberately NOT calling preventDefault(): the atomic install
      // happens server-side in a single normal POST request, exactly as
      // before this UI redesign. We just show a progress overlay on top
      // of the same page while the browser waits for that request to
      // finish and navigate to the response (success or an error state).
    });
  }

  showStep(startStep);
})();
