// /assets/js/validate_student.js
import { validateNameLive } from './name_validation.js';
import { validateEmailLive } from './email_validation.js';
import { validatePhoneLive } from './phone_validation.js';
import { validateAgeLive } from './age_validation.js';

(function () {
  document.addEventListener('DOMContentLoaded', function () {
    var form = document.getElementById('studentRegistrationForm');
    if (!form) return;

    // ---- Polyfills / helpers ----
    var CSS_ESCAPE = (window.CSS && typeof window.CSS.escape === 'function')
      ? window.CSS.escape
      : function (s) { return String(s).replace(/[^a-zA-Z0-9_\-]/g, '\\$&'); };

    function log() { try { console.log.apply(console, arguments); } catch (_) { } }
    function warn() { try { console.warn.apply(console, arguments); } catch (_) { } }
    function err() { try { console.error.apply(console, arguments); } catch (_) { } }

    // ---- Config ----
    var MIN_AGE = 5;
    var MAX_AGE = 18;

    var maxStudents = parseInt(form.dataset.maxStudents, 10) || 6;
    var existingStudents = parseInt(form.dataset.existingStudents, 10) || 0;
    var maxEmergency = parseInt(form.dataset.maxEmergency, 10) || 1;
    var existingEmergencies = parseInt(form.dataset.existingEmergencies, 10) || 0;

    // Only allow emergency forms if there are NO registered students in DB
    var allowEmergency = (existingStudents === 0);

    // ---- DOM ----
    var container = document.getElementById('studentFormsContainer');
    var emergencyContainer = document.getElementById('emergencyFormsContainer');
    var addStudentBtn = document.getElementById('addStudentBtn');
    var addAnotherStudentBtn = document.getElementById('addAnotherStudentBtn');
    var doneWithStudentBtn = document.getElementById('doneWithStudentBtn');
    var saveFormBtn = document.getElementById('saveFormBtn'); // should be type="submit"
    var initialButtons = document.getElementById('initialButtons');
    var formActionButtons = document.getElementById('formActionButtons');
    var studentTmplWrap = document.getElementById('studentFormTemplate');
    var contactTmplWrap = document.getElementById('emergencyFormTemplate');

    var addedStudents = 0;
    var addedEmergencies = 0;
    var isSubmitting = false; // re-entrancy guard


    // ---- Group validators (at least one required; 'Other' requires text) ----
    function ensureFeedback(container, idBase, message) {
      var fb = container.querySelector('.invalid-feedback[data-for="' + idBase + '"]');
      if (!fb) {
        fb = document.createElement('div');
        fb.className = 'invalid-feedback';
        fb.setAttribute('data-for', idBase);
        container.appendChild(fb);
      }
      fb.textContent = message || '';
      fb.style.display = message ? 'block' : 'none';
      return fb;
    }

    function validateChecklistRequired(block, baseName, otherInputName, labelText) {
      var groupWrap = block.querySelector('[data-group="' + baseName + '"]') || block; // optional wrapper
      var boxes = block.querySelectorAll('input[type="checkbox"][data-base-name="' + baseName + '"]');
      if (!boxes.length) return true;
      var idBase = baseName + '-' + (block.dataset.index || '');

      var anyChecked = Array.prototype.some.call(boxes, function (b) { return b.checked; });
      var firstBox = boxes[0];
      var valid = true;
      var msg = '';

      if (!anyChecked) {
        valid = false;
        msg = 'Please select at least one ' + (labelText || baseName.replace('_', ' ')) + '.';
      } else {
        // If "Other" is checked, ensure text provided
        var otherChecked = Array.prototype.some.call(boxes, function (b) { return /Other$/i.test(b.value) && b.checked; });
        if (otherChecked) {
          var otherInput = block.querySelector(
            'input[name="' + otherInputName + '"], input[data-other-for="' + baseName + '"]'
          );
          if (otherInput) {
            var val = (otherInput.value || '').trim();
            if (!val) {
              valid = false;
              msg = "Please specify the 'Other' " + (labelText || baseName.replace('_', ' ')) + '.';
              // mark 'other' input invalid too
              otherInput.classList.add('is-invalid');
              otherInput.setCustomValidity(msg);
            } else {
              otherInput.classList.remove('is-invalid');
              otherInput.setCustomValidity('');
            }
          }
        }
      }

      // apply validity to first checkbox (so browser can focus it)
      if (!valid) {
        firstBox.classList.add('is-invalid');
        firstBox.setCustomValidity(msg);
        try { firstBox.scrollIntoView({ behavior: 'smooth', block: 'center' }); } catch (_) { }
      } else {
        boxes.forEach(function (b) { b.classList.remove('is-invalid'); b.setCustomValidity(''); });

        var otherInput = block.querySelector(
          'input[name="' + otherInputName + '"], input[data-other-for="' + baseName + '"]'
        );
        if (otherInput) { otherInput.classList.remove('is-invalid'); otherInput.setCustomValidity(''); }
      }

      // show/hide feedback message
      ensureFeedback(groupWrap, idBase, msg);
      return valid;
    }

    // ---- Utilities ----
    function cloneTemplateContent(wrapper) {
      var temp = document.createElement('div');
      temp.innerHTML = (wrapper && wrapper.innerHTML ? wrapper.innerHTML : '').trim();
      return temp.firstElementChild || null;
    }

    function showToast(message, type) {
      type = type || 'success';
      var toast = document.createElement('div');
      toast.className = 'alert alert-' + type + ' position-fixed top-0 end-0 m-3';
      toast.style.zIndex = '9999';
      toast.textContent = message;
      document.body.appendChild(toast);
      setTimeout(function () { if (toast && toast.parentNode) toast.parentNode.removeChild(toast); }, 3000);
    }

    function reindexForms() {
      var forms = container.querySelectorAll('.student-form');
      forms.forEach(function (formEl, index) {
        formEl.querySelectorAll('[data-base-name]').forEach(function (input) {
          var base = input.dataset.baseName;
          if (input.type === 'radio') {
            input.name = base + '_' + index;
            input.id = base + '_' + index + '_' + input.value;
          } else if (input.type === 'checkbox') {
            input.name = base + '[' + index + '][]';
          } else {
            input.name = base + '[' + index + ']';
          }
        });
      });
    }

    function updateButtonStates() {
      var totalStudents = existingStudents + addedStudents;
      var remainingStudents = maxStudents - totalStudents;
      var hasStudentForms = container.querySelectorAll('.student-form').length > 0;

      // Reset
      if (initialButtons) initialButtons.classList.add('d-none');
      if (formActionButtons) formActionButtons.classList.add('d-none');
      if (saveFormBtn) saveFormBtn.classList.add('d-none');
      if (doneWithStudentBtn) doneWithStudentBtn.classList.add('d-none');

      // 1) no existing + no draft -> show initial Add
      if (existingStudents === 0 && !hasStudentForms) {
        if (initialButtons) initialButtons.classList.remove('d-none');
        if (addStudentBtn) addStudentBtn.classList.remove('d-none');
        return;
      }

      // 2) existing students present + no draft -> show "Add Another"
      if (existingStudents > 0 && !hasStudentForms) {
        if (formActionButtons) formActionButtons.classList.remove('d-none');
        if (addAnotherStudentBtn) {
          addAnotherStudentBtn.classList.remove('d-none');
          var atMax = (totalStudents >= maxStudents);
          addAnotherStudentBtn.disabled = atMax;
          addAnotherStudentBtn.title = atMax
            ? ('Maximum of ' + maxStudents + ' students reached')
            : ('Add student (' + remainingStudents + ' remaining)');
        }
        return;
      }

      // 3) at least one draft student form
      if (formActionButtons) formActionButtons.classList.remove('d-none');
      if (doneWithStudentBtn) doneWithStudentBtn.classList.remove('d-none');

      var atMaxStudents = totalStudents >= maxStudents;
      if (addAnotherStudentBtn) {
        addAnotherStudentBtn.disabled = atMaxStudents;
        addAnotherStudentBtn.title = atMaxStudents
          ? ('Maximum of ' + maxStudents + ' students reached')
          : ('Add student (' + remainingStudents + ' remaining)');
        if (atMaxStudents && !hasStudentForms) {
          addAnotherStudentBtn.classList.add('d-none');
        }
      }
    }

    function initializeLiveValidation(scope) {
      scope.querySelectorAll('input[data-base-name="studentFirstName"], input[data-base-name="studentLastName"], input[data-base-name="emergency_firstname"], input[data-base-name="emergency_lastname"]').forEach(function (el) {
        el.addEventListener('input', function () { validateNameLive(el); });
        el.title = 'Only letters, spaces, or dashes (2–30 chars)';
      });

      scope.querySelectorAll('input[data-base-name="emergency_email"]').forEach(function (el) {
        el.addEventListener('input', function () { validateEmailLive(el); });
        el.title = 'Email must be in the format: user@example.com';
      });

      scope.querySelectorAll('input[data-base-name="emergency_phone"]').forEach(function (el) {
        el.addEventListener('input', function () { validatePhoneLive(el); });
        el.title = 'Phone number must be 10 digits, e.g., 123-456-7890';
      });

      scope.querySelectorAll('input[data-base-name="dob"]').forEach(function (el) {
        el.addEventListener('input', function () { validateAgeLive(el, MIN_AGE, MAX_AGE); });
        el.title = 'Age must be between ' + MIN_AGE + ' and ' + MAX_AGE;
      });
      wireChecklistLiveValidation(scope);
    }

    function validateRadioGroup(scope, baseName) {
      var radios = scope.querySelectorAll('input[data-base-name="' + baseName + '"][type="radio"]');
      if (!radios.length) return true;

      var names = Array.from(new Set(Array.from(radios).map(function (r) { return r.name; })));
      var ok = true;

      names.forEach(function (n) {
        var group = scope.querySelectorAll('input[name="' + CSS_ESCAPE(n) + '"]');
        var oneChecked = Array.from(group).some(function (r) { return r.checked; });
        group.forEach(function (r) { r.setCustomValidity(oneChecked ? '' : 'Please select an option.'); });
        ok = ok && oneChecked;
      });

      return ok;
    }

    function findFirstInvalid(formEl) {
      var candidates = formEl.querySelectorAll('input, select, textarea');
      for (var i = 0; i < candidates.length; i++) {
        var el = candidates[i];
        if (!el.checkValidity()) return el;
      }
      return null;
    }

    function setDefaultsForNewStudentForm(formEl) {
      // Do NOT preselect any radio
      formEl.querySelectorAll('input[type="radio"][data-base-name="last_year"]').forEach(function (r) {
        r.checked = false;
      });

      // Keep grade select disabled until a choice is made
      var gradeSelect = formEl.querySelector('.grade-select');
      var gradeLabel = formEl.querySelector('.grade-label');
      if (gradeSelect && gradeLabel) {
        gradeSelect.innerHTML = '<option value="">Select Grade</option>';
        gradeSelect.disabled = true;
        gradeLabel.innerHTML = 'Last Year Grade <span class="text-danger">*</span>';
      }
    }

function addStudentForm() {
  if (existingStudents + addedStudents >= maxStudents) {
    showToast('Maximum of ' + maxStudents + ' students reached', 'info');
    updateButtonStates();
    return false;
  }
  var clone = cloneTemplateContent(studentTmplWrap);
  if (!clone) return false;

  // ✅ ensure marker class exists
  if (!clone.classList.contains('student-form')) clone.classList.add('student-form');

  container.classList.remove('d-none');
  container.appendChild(clone);
  addedStudents++;

  reindexForms();
  setDefaultsForNewStudentForm(clone);
  initializeLiveValidation(clone);
  updateButtonStates();
  return true;
}

function addEmergencyForm() {
  if (!allowEmergency) return false;
  if (existingEmergencies + addedEmergencies >= maxEmergency) return false;

  var clone = cloneTemplateContent(contactTmplWrap);
  if (!clone) return false;

  // ✅ ensure marker class exists
  if (!clone.classList.contains('emergency-contact-form')) clone.classList.add('emergency-contact-form');

  emergencyContainer.classList.remove('d-none');
  emergencyContainer.appendChild(clone);
  addedEmergencies++;

  initializeLiveValidation(clone);
  updateButtonStates();
  return true;
}


    // Disable emergency inputs that shouldn’t participate in THIS submit
    function neutralizeEmergencyBlocksForSubmit(formEl, allow) {
      var blocks = formEl.querySelectorAll('.emergency-contact-form');
      var disabledInputs = [];
      if (!blocks.length) return { disabledInputs: disabledInputs };

      if (!allow) {
        blocks.forEach(function (block) {
          block.querySelectorAll('input, select, textarea').forEach(function (el) {
            if (!el.disabled) {
              el.disabled = true;
              disabledInputs.push(el);
            }
            el.setCustomValidity('');
          });
        });
        return { disabledInputs: disabledInputs };
      }

      // allow === true: disable completely empty blocks so 'required' won't trigger
      blocks.forEach(function (block) {
        var fields = block.querySelectorAll('input, select, textarea');
        var anyFilled = Array.from(fields).some(function (el) { return (el.value || '').trim().length > 0; });
        if (!anyFilled) {
          fields.forEach(function (el) {
            if (!el.disabled) {
              el.disabled = true;
              disabledInputs.push(el);
            }
            el.setCustomValidity('');
          });
        }
      });

      return { disabledInputs: disabledInputs };
    }

    // ---- Listeners ----
    if (addStudentBtn && studentTmplWrap) {
      addStudentBtn.addEventListener('click', function () {
        if (addStudentForm()) updateButtonStates();
      });
    }

    if (addAnotherStudentBtn && studentTmplWrap) {
      addAnotherStudentBtn.addEventListener('click', function () {
        if (addStudentForm()) updateButtonStates();
      });
    }

    if (doneWithStudentBtn) {
      doneWithStudentBtn.addEventListener('click', function () {
        var hasEmergencyForms = emergencyContainer.querySelectorAll('.emergency-contact-form').length > 0;
        if (allowEmergency && !hasEmergencyForms) addEmergencyForm(); // first-time family
        if (saveFormBtn) saveFormBtn.classList.remove('d-none');
        doneWithStudentBtn.classList.add('d-none');
      });
    }

    // --- Delete student (SAFE: only intercept draft .student-form) ---
    function handleRemoveStudentClick(e) {
      const btn = e.target.closest('.js-remove-student');
      if (!btn) return;

      // If the button is NOT inside a draft student form, let native behavior proceed
      const draftBlock = btn.closest('.student-form');
      if (!draftBlock) return;

      // Draft delete: prevent submit and remove the block
      e.preventDefault();
      e.stopPropagation();

      if (draftBlock.parentNode) draftBlock.parentNode.removeChild(draftBlock);
      addedStudents = Math.max(0, addedStudents - 1);

      reindexForms();
      updateButtonStates();

      if (!container.querySelectorAll('.student-form').length) {
        if (emergencyContainer) {
          emergencyContainer.innerHTML = '';
          addedEmergencies = 0;
          updateButtonStates();
        }
      }
    }

    // Attach listeners (capture = true to beat other handlers)
    if (container) container.addEventListener('click', handleRemoveStudentClick, true);
    document.addEventListener('click', handleRemoveStudentClick, true);

    if (emergencyContainer) {
      emergencyContainer.addEventListener('click', function (e) {
        var btn = e.target.closest('.js-remove-contact');
        if (!btn) return;
        var block = btn.closest('.emergency-contact-form');
        if (!block) return;

        block.remove();
        addedEmergencies = Math.max(0, addedEmergencies - 1);
        updateButtonStates();
      });
    }

    // Enable grade select only after the last_year radio is chosen
    container.addEventListener('change', function (e) {
      var target = e.target;
      if (target && target.matches('input[type="radio"][data-base-name="last_year"]') && target.checked) {
        var studentForm = target.closest('.student-form');
        if (!studentForm) return;

        if (typeof window.updateGradeOptions === 'function') {
          try { window.updateGradeOptions(studentForm, target.value); } catch (ex) { warn('updateGradeOptions error', ex); }
        } else {
          var gradeSelect = studentForm.querySelector('.grade-select');
          if (gradeSelect) gradeSelect.disabled = false;
        }
      }
    });

    // ---- Submit & Validation ----
    form.addEventListener('submit', function (e) {
      try {
        console.log('submit handler: start', { action: form.action, method: form.method });

        if (isSubmitting) {
          console.warn('submit handler: already submitting — ignored');
          e.preventDefault();
          return;
        }

        // Disable empty/blocked emergency inputs for THIS attempt
        const { disabledInputs } = neutralizeEmergencyBlocksForSubmit(form, allowEmergency);

        // ✅ Robust presence detection based on enabled fields inside containers
        const studentInputs = form.querySelectorAll(
          '#studentFormsContainer input, #studentFormsContainer select, #studentFormsContainer textarea'
        );
        const emergencyInputs = form.querySelectorAll(
          '#emergencyFormsContainer input, #emergencyFormsContainer select, #emergencyFormsContainer textarea'
        );

        const hasStudentForms   = Array.from(studentInputs).some(el => !el.disabled);
        const hasEmergencyForms = allowEmergency && Array.from(emergencyInputs).some(el => !el.disabled);

        if (!hasStudentForms && !hasEmergencyForms) {
          const proceed = confirm('No student or emergency forms detected. Submit anyway?');
          if (!proceed) {
            e.preventDefault();
            // re-enable so user can edit
            disabledInputs.forEach(el => el.disabled = false);
            console.warn('submit handler: user canceled — no forms present', {
              studentInputs: studentInputs.length,
              studentEnabled: Array.from(studentInputs).filter(el => !el.disabled).length,
              emergencyInputs: emergencyInputs.length,
              emergencyEnabled: Array.from(emergencyInputs).filter(el => !el.disabled).length,
              allowEmergency
            });
            return;
          }
        }

        let allValid = true;

        // Validate non-emergency inputs (per your existing rules)
        form.querySelectorAll('input[data-base-name]:not([data-base-name^="emergency_"])').forEach((input) => {
          const base = input.dataset.baseName;
          let valid = true;
          if (base === 'studentFirstName' || base === 'studentLastName') valid = validateNameLive(input);
          else if (base === 'dob') valid = validateAgeLive(input, MIN_AGE, MAX_AGE);
          input.setCustomValidity(valid ? '' : 'Please fix this field.');
          allValid = allValid && valid;
        });

        // Required selects (skip disabled)
        form.querySelectorAll('select[required]').forEach((sel) => {
          if (sel.disabled) { sel.setCustomValidity(''); return; }
          const ok = sel.value !== '';
          sel.setCustomValidity(ok ? '' : 'Please choose an option.');
          allValid = allValid && ok;
        });

        // Radio groups per student (e.g., last_year)
        form.querySelectorAll('.student-form').forEach((sf) => {
          const radiosOk = validateRadioGroup(sf, 'last_year');
          allValid = allValid && radiosOk;
        });

        // ---- Validate allergies & medical conditions for each student ----
        let groupOk = true;
        form.querySelectorAll('.student-form').forEach(function (block, idx) {
          block.dataset.index = String(idx); // used for feedback id base
          const ok1 = validateChecklistRequired(block, 'allergies', 'allergy_other[]', 'allergy');
          const ok2 = validateChecklistRequired(block, 'medical_conditions', 'medical_condition_other[]', 'medical condition');
          if (!ok1 || !ok2) groupOk = false;
        });
        allValid = allValid && groupOk;

        // Emergency (allowed + non-empty blocks only)
        if (allowEmergency) {
          form.querySelectorAll('.emergency-contact-form').forEach(block => {
            const anyEnabled = block.querySelector('input:not(:disabled), select:not(:disabled), textarea:not(:disabled)');
            if (!anyEnabled) return; // empty block was disabled above

            block.querySelectorAll('input[data-base-name]').forEach(input => {
              const base = input.dataset.baseName;
              let valid = true;
              if (base === 'emergency_firstname' || base === 'emergency_lastname') valid = validateNameLive(input);
              else if (base === 'emergency_email') valid = validateEmailLive(input);
              else if (base === 'emergency_phone') valid = validatePhoneLive(input);
              input.setCustomValidity(valid ? '' : 'Please fix this field.');
              allValid = allValid && valid;
            });
          });
        }

        // Final check
        if (!form.checkValidity() || !allValid) {
          e.preventDefault();
          const firstBad = (function findFirstInvalid(formEl) {
            const nodes = formEl.querySelectorAll('input, select, textarea');
            for (const el of nodes) { if (!el.checkValidity()) return el; }
            return null;
          })(form);
          if (firstBad) {
            console.warn('First invalid:', firstBad, firstBad.name, firstBad.dataset && firstBad.dataset.baseName, firstBad.validationMessage);
            try { firstBad.scrollIntoView({ behavior: 'smooth', block: 'center' }); } catch (_) { }
          }
          form.reportValidity();
          disabledInputs.forEach(el => el.disabled = false); // keep editable
          console.warn('submit handler: blocked — invalid');
          return;
        }

        // ✅ SUCCESS: post once, outside this tick (bypass submit handlers)
        e.preventDefault();
        isSubmitting = true;
        console.log('submit handler: valid — posting via form.submit()');
        setTimeout(function () { form.submit(); }, 0);

      } catch (ex) {
        console.error('submit handler: exception', ex);
        try { e.preventDefault(); } catch (_) { }
      }
    });

    function revalidateChecklistGroup(el) {
      const block = el.closest('.student-form');
      if (!block) return;
      // Ensure stable id base
      if (!block.dataset.index) {
        const list = Array.from(block.parentNode.querySelectorAll('.student-form'));
        block.dataset.index = String(list.indexOf(block));
      }
      // Re-validate both groups (safe + simple)
      validateChecklistRequired(block, 'allergies', 'allergy_other[]', 'allergy');
      validateChecklistRequired(block, 'medical_conditions', 'medical_condition_other[]', 'medical condition');
    }

    function wireChecklistLiveValidation(scope) {
      // Check/uncheck boxes
      scope.addEventListener('change', function (e) {
        const t = e.target;
        if (!t) return;
        if (t.matches('input[type="checkbox"][data-base-name="allergies"]') ||
          t.matches('input[type="checkbox"][data-base-name="medical_conditions"]')) {
          revalidateChecklistGroup(t);
        }
      });

      // Typing in the "Other" input
      scope.addEventListener('input', function (e) {
        const t = e.target;
        if (!t) return;
        if (t.matches('input[name="allergy_other[]"], input[name="medical_condition_other[]"], input[data-other-for="allergies"], input[data-other-for="medical_conditions"]')) {
          revalidateChecklistGroup(t);
        }
      });
    }


    // ---- Init ----
    initializeLiveValidation(form);
    wireChecklistLiveValidation(form);
    updateButtonStates();

    // If server repopulated radios, reflect in grade select
    container.querySelectorAll('.student-form').forEach(function (sf) {
      var checked = sf.querySelector('input[type="radio"][data-base-name="last_year"]:checked');
      if (checked && typeof window.updateGradeOptions === 'function') {
        try { window.updateGradeOptions(sf, checked.value); } catch (ex) { warn('updateGradeOptions init error', ex); }
      }
    });

    log('validate_student.js loaded', {
      maxStudents: maxStudents,
      existingStudents: existingStudents,
      maxEmergency: maxEmergency,
      existingEmergencies: existingEmergencies,
      allowEmergency: allowEmergency
    });
  });
})();