(function () {
  'use strict';

  const STEPS = [
    { id: 'location', label: 'Location & Identity', fields: ['clucd'] },
    { id: 'personal', label: 'Personal Details', fields: ['cwsn_name', 'dob', 'gender', 'cwsn_f_name', 'cwsn_m_name', 'contact_no', 'manabik_yn'] },
    { id: 'address', label: 'Address', fields: ['add1', 'add2', 'add3', 'pin'] },
    { id: 'disability', label: 'Disability & Support', fields: ['disability_id', 'dis_certi_yn', 'therapy_reqd_yn'] },
    { id: 'education', label: 'Education Status', fields: ['in_school_yn'] },
    { id: 'bank', label: 'Bank Details', fields: [] },
    { id: 'review', label: 'Review & Save', fields: [] },
  ];
  const CLASS_LABELS = ['PP', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII'];

  const root = document.getElementById('wizardRoot');
  let savedCode = IS_EDIT ? root.dataset.code : null;
  let currentStep = 0;

  const form = Object.assign({}, INITIAL);
  form.schcat_id = '';

  function $(id) { return document.getElementById(id); }
  function normText(s) { return (s || '').toString().trim().toUpperCase().replace(/\s+/g, ' '); }
  function udiseClassLabel(code) {
    const n = parseInt(code, 10);
    if (!isNaN(n) && n >= 0 && n < CLASS_LABELS.length) return CLASS_LABELS[n];
    return code || '';
  }
  function maskAadhaar(raw) {
    raw = raw || '';
    if (raw.length <= 4) return raw;
    return '•'.repeat(raw.length - 4) + raw.slice(-4);
  }
  function nameOf(list, code, codeField, nameField) {
    if (!code) return '';
    const found = list.find((x) => String(x[codeField]) === String(code));
    return found ? found[nameField] : code;
  }
  function escapeHtml(s) {
    return (s || '').toString().replace(/[&<>"']/g, (m) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[m]));
  }

  // ---- Field <-> form sync ----
  const FIELD_IDS = [
    'clrccode', 'clucd', 'cwsn_name', 'dob', 'gender', 'cwsn_f_name', 'cwsn_m_name', 'legalgurdian',
    'contact_no', 'manabik_yn', 'add1', 'add2', 'add3', 'pin', 'disability_id', 'dis_certi_yn',
    'dis_certi_valid_yn', 'appliance_id', 'therapy_reqd_yn', 'therapy_provide_yn', 'spledu_reg_no',
    'in_school_yn', 'school_awc', 'class', 'date_of_entry', 'pen', 'acno', 'ac_holder',
  ];
  function bindSimpleFields() {
    FIELD_IDS.forEach((key) => {
      const el = $('f_' + key);
      if (!el) return;
      if (el.value === '' && form[key]) el.value = form[key];
      el.addEventListener('input', () => { form[key] = el.value; clearFieldError(key); });
      el.addEventListener('change', () => { form[key] = el.value; clearFieldError(key); });
    });
  }
  function clearFieldError(key) {
    const errEl = document.querySelector('[data-err="' + key + '"]');
    if (errEl) { errEl.classList.add('hidden'); errEl.textContent = ''; }
    const inputEl = $('f_' + key);
    if (inputEl) inputEl.classList.remove('error');
  }
  function showFieldErrors(errors) {
    document.querySelectorAll('[data-err]').forEach((el) => { el.classList.add('hidden'); el.textContent = ''; });
    document.querySelectorAll('.field-input, .field-select').forEach((el) => el.classList.remove('error'));
    Object.keys(errors || {}).forEach((key) => {
      const errEl = document.querySelector('[data-err="' + key + '"]');
      if (errEl) { errEl.textContent = errors[key]; errEl.classList.remove('hidden'); }
      const inputEl = $('f_' + key);
      if (inputEl) inputEl.classList.add('error');
    });
  }

  // ---- Location & Identity ----
  function populateClusters() {
    const sel = $('f_clucd');
    const clrccode = form.clrccode;
    const opts = MASTER.clusters.filter((c) => !clrccode || c.clrccode === clrccode);
    sel.innerHTML = '<option value="">Select school / cluster</option>' +
      opts.map((c) => `<option value="${c.clucd}" ${c.clucd === form.clucd ? 'selected' : ''}>${escapeHtml(c.cluname)}</option>`).join('');
  }
  $('f_clrccode').addEventListener('change', () => {
    form.clrccode = $('f_clrccode').value;
    form.clucd = '';
    populateClusters();
  });
  $('f_clucd').addEventListener('change', () => { form.clucd = $('f_clucd').value; clearFieldError('clucd'); });

  // ---- Aadhaar masking (append/remove-at-end heuristic) ----
  const aadhaarDisplay = $('f_aadhaar_display');
  form.aadhaar = INITIAL.aadhaar || '';
  aadhaarDisplay.value = maskAadhaar(form.aadhaar);
  aadhaarDisplay.addEventListener('input', () => {
    const raw = form.aadhaar || '';
    const prevDisplay = maskAadhaar(raw);
    const newValue = aadhaarDisplay.value;
    if (!newValue.includes('•')) {
      form.aadhaar = newValue.replace(/\D/g, '').slice(0, 12);
    } else {
      const delta = newValue.length - prevDisplay.length;
      if (delta > 0) {
        const added = newValue.slice(prevDisplay.length).replace(/\D/g, '');
        form.aadhaar = (raw + added).slice(0, 12);
      } else if (delta < 0) {
        form.aadhaar = raw.slice(0, Math.max(0, raw.length + delta));
      }
    }
    aadhaarDisplay.value = maskAadhaar(form.aadhaar);
    clearFieldError('aadhaar');
  });

  // ---- Conditional field visibility ----
  function updateConditionals() {
    toggle('wrap_dis_certi_valid_yn', form.dis_certi_yn === 'YES');
    toggle('wrap_therapy_provide_yn', form.therapy_reqd_yn === 'YES');
    toggle('wrap_school_awc', form.in_school_yn === 'YES');
    toggle('wrap_school_fields', form.school_awc === 'SCHOOL');
    toggle('wrap_awc_field', form.school_awc === 'AWC');
  }
  function toggle(id, show) { $(id).classList.toggle('hidden', !show); }

  $('f_dis_certi_yn').addEventListener('change', () => { form.dis_certi_yn = $('f_dis_certi_yn').value; if (form.dis_certi_yn !== 'YES') form.dis_certi_valid_yn = ''; updateConditionals(); });
  $('f_therapy_reqd_yn').addEventListener('change', () => { form.therapy_reqd_yn = $('f_therapy_reqd_yn').value; if (form.therapy_reqd_yn !== 'YES') form.therapy_provide_yn = ''; updateConditionals(); });
  $('f_in_school_yn').addEventListener('change', () => {
    form.in_school_yn = $('f_in_school_yn').value;
    if (form.in_school_yn !== 'YES') { form.school_awc = ''; form.schcd = ''; form.class = ''; form.awc_no = ''; $('f_school_awc').value = ''; }
    updateConditionals();
  });
  $('f_school_awc').addEventListener('change', () => {
    form.school_awc = $('f_school_awc').value;
    if (form.school_awc !== 'SCHOOL') { form.schcd = ''; form.class = ''; $('f_schcd_display').value = ''; }
    if (form.school_awc !== 'AWC') { form.awc_no = ''; $('f_awc_no_display').value = ''; }
    if (form.school_awc === 'SCHOOL') ensureSchoolScopeUi();
    updateConditionals();
  });

  // ---- Generic searchable dropdown ----
  function initSearchable(inputId, resultsId, fetchFn, onSelect) {
    const input = $(inputId);
    const results = $(resultsId);
    let timer = null;
    input.addEventListener('input', () => {
      clearTimeout(timer);
      const q = input.value.trim();
      timer = setTimeout(async () => {
        const items = await fetchFn(q);
        renderResults(items);
      }, 250);
    });
    input.addEventListener('focus', () => { if (results.children.length) results.classList.add('open'); });
    document.addEventListener('click', (e) => { if (!input.contains(e.target) && !results.contains(e.target)) results.classList.remove('open'); });
    function renderResults(items) {
      if (!items.length) { results.innerHTML = '<div class="searchable-item text-slate-400">No matches found.</div>'; results.classList.add('open'); return; }
      results.innerHTML = items.map((it, i) =>
        `<div class="searchable-item" data-idx="${i}">${escapeHtml(it.label)}${it.sublabel ? `<div class="sub">${escapeHtml(it.sublabel)}</div>` : ''}</div>`
      ).join('');
      results.classList.add('open');
      results.querySelectorAll('.searchable-item[data-idx]').forEach((el) => {
        el.addEventListener('click', () => {
          const item = items[parseInt(el.dataset.idx, 10)];
          input.value = item.label;
          results.classList.remove('open');
          onSelect(item);
        });
      });
    }
  }

  async function apiGet(url) {
    const res = await fetch(url);
    if (res.status === 401) { window.location.href = 'login.php'; return []; }
    return res.json();
  }
  async function apiPostForm(url, data) {
    const body = new URLSearchParams(data).toString();
    const res = await fetch(url, { method: 'POST', body, headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });
    if (res.status === 401) { window.location.href = 'login.php'; return { status: 401, json: {} }; }
    return { status: res.status, json: await res.json() };
  }

  // School search (scoped to a chosen CLRC/Block, defaults to the CWSN's own)
  let schoolSearchClrc = form.clrccode || '';
  function ensureSchoolScopeUi() {
    const wrap = $('wrap_school_fields');
    if (wrap.querySelector('#f_school_scope')) return;
    const div = document.createElement('div');
    div.innerHTML = `<label class="field-label">Search schools within</label>
      <select id="f_school_scope" class="field-select">
        <option value="">-- Select CLRC / Block --</option>
        ${MASTER.clrc.map((c) => `<option value="${c.clrccode}">${escapeHtml(c.clrcname)}</option>`).join('')}
      </select>
      <div class="field-hint">Defaults to the CWSN's own CLRC/Block. Change this if admitted outside their home block.</div>`;
    wrap.insertBefore(div, wrap.firstChild);
    $('f_school_scope').value = schoolSearchClrc;
    $('f_school_scope').addEventListener('change', () => {
      schoolSearchClrc = $('f_school_scope').value;
      form.schcd = ''; $('f_schcd_display').value = '';
    });
  }
  initSearchable('f_schcd_display', 'schoolResults', async (q) => {
    if (!schoolSearchClrc) return [];
    return apiGet(`api/search.php?type=school&clrccode=${encodeURIComponent(schoolSearchClrc)}&q=${encodeURIComponent(q)}`);
  }, (item) => {
    form.schcd = item.value;
    form.schcat_id = item.schcat_id;
    form.class = '';
    populateClasses();
    clearFieldError('schcd');
  });

  function populateClasses() {
    const sel = $('f_class');
    if (!form.schcat_id) { sel.innerHTML = '<option value="">Select a school first</option>'; sel.disabled = true; return; }
    sel.disabled = false;
    const opts = MASTER.classes.filter((c) => String(c.schcat_id) === String(form.schcat_id));
    const seen = new Set();
    let html = '<option value="">Select class</option>';
    opts.forEach((c) => { if (!seen.has(c.sclass)) { seen.add(c.sclass); html += `<option value="${escapeHtml(c.sclass)}" ${c.sclass === form.class ? 'selected' : ''}>${escapeHtml(c.sclass)}</option>`; } });
    sel.innerHTML = html;
  }
  $('f_class').addEventListener('change', () => { form.class = $('f_class').value; clearFieldError('class'); });

  initSearchable('f_awc_no_display', 'awcResults', (q) => apiGet(`api/search.php?type=awc&q=${encodeURIComponent(q)}`), (item) => {
    form.awc_no = item.value;
    clearFieldError('awc_no');
  });

  // ---- Bank Details: IFSC-first ----
  initSearchable('f_ifsc_display', 'ifscResults', (q) => apiGet(`api/search.php?type=ifsc&q=${encodeURIComponent(q)}`), async (item) => {
    form.ifsc = item.value;
    const branches = await apiGet(`api/search.php?type=branches_for_ifsc&ifsc=${encodeURIComponent(item.value)}`);
    if (branches.length === 1) {
      applyBranch(branches[0]);
      toggle('wrap_branch_pick', false);
      toggle('wrap_branch_readonly', true);
    } else if (branches.length > 1) {
      form.bank_id = branches[0].bank_id;
      $('f_bank_id').value = branches[0].bank_id;
      $('f_bank_display').value = branches[0].bank_name;
      form.branch_name = ''; form.micr = '';
      $('f_branch_name').value = ''; $('f_micr').value = '';
      const sel = $('f_branch_pick');
      sel.innerHTML = '<option value="">-- Select your branch --</option>' +
        branches.map((b, i) => `<option value="${i}">${escapeHtml(b.label)}${b.sublabel ? ' — ' + escapeHtml(b.sublabel) : ''}</option>`).join('');
      sel.onchange = () => { if (sel.value !== '') applyBranch(branches[parseInt(sel.value, 10)]); };
      toggle('wrap_branch_pick', true);
      toggle('wrap_branch_readonly', false);
    }
    clearFieldError('ifsc');
  });
  function applyBranch(b) {
    form.bank_id = b.bank_id; form.branch_name = b.value; form.micr = b.micr || '';
    $('f_bank_id').value = b.bank_id;
    $('f_bank_display').value = b.bank_name || nameOf(MASTER.banks, b.bank_id, 'bank_id', 'bank_name');
    $('f_branch_name').value = b.value;
    $('f_micr').value = b.micr || '';
    clearFieldError('branch_name');
  }
  function populateAccountHolder() {
    const sel = $('f_ac_holder');
    const opts = [];
    const seen = new Set();
    const add = (name, tag) => { const v = (name || '').trim(); if (v && !seen.has(v)) { seen.add(v); opts.push({ v, label: `${v} (${tag})` }); } };
    add(form.cwsn_name, 'CWSN'); add(form.cwsn_f_name, 'Father'); add(form.cwsn_m_name, 'Mother');
    sel.innerHTML = (opts.length ? '<option value="">Select account holder</option>' : '<option value="">Fill in names first</option>') +
      opts.map((o) => `<option value="${escapeHtml(o.v)}" ${o.v === form.ac_holder ? 'selected' : ''}>${escapeHtml(o.label)}</option>`).join('');
  }
  $('f_ac_holder').addEventListener('change', () => { form.ac_holder = $('f_ac_holder').value; clearFieldError('ac_holder'); });

  // ---- UDISE+ Match Check ----
  $('btnUdiseCheck').addEventListener('click', async () => {
    const btn = $('btnUdiseCheck');
    btn.disabled = true; btn.textContent = 'Checking...';
    try {
      const { json } = await apiPostForm('api/udise_check.php', {
        aadhaar: form.aadhaar || '', cwsn_name: form.cwsn_name || '', cwsn_f_name: form.cwsn_f_name || '',
        cwsn_m_name: form.cwsn_m_name || '', dob: form.dob || '',
      });
      renderUdiseResult(json);
    } finally {
      btn.disabled = false; btn.textContent = 'Check UDISE+ Match';
    }
  });
  function renderUdiseResult(res) {
    const el = $('udiseResult');
    if (!res.matched) {
      el.innerHTML = '<div class="rounded-lg bg-white border border-slate-200 px-3 py-2 text-sm text-slate-500">No UDISE+ match found for the current details.</div>';
      return;
    }
    const u = res.udise;
    const items = [
      { key: 'pen', label: 'PEN', pullValue: u.pen || '', formValue: form.pen || '' },
      { key: 'aadhaar', label: 'Aadhaar Number', pullValue: u.aadhaar_no || '', formValue: form.aadhaar || '', display: maskAadhaar(u.aadhaar_no) },
      { key: 'contact_no', label: 'Contact Number', pullValue: u.mobile_no_1 || '', formValue: form.contact_no || '' },
      { key: 'class', label: 'Class', pullValue: udiseClassLabel(u.class_id), formValue: form.class || '' },
    ].filter((f) => f.pullValue);
    let html = `<div class="rounded-lg bg-white border border-teal-200 p-3 space-y-2">
      <div class="text-sm font-semibold text-teal-700">Matched by ${res.matchType === 'AADHAAR' ? 'Aadhaar number' : "Name + Father's + Mother's Name + DOB"}</div>
      <div class="grid grid-cols-1 sm:grid-cols-2 gap-2 text-sm">`;
    items.forEach((f) => {
      const matches = f.formValue && normText(f.formValue) === normText(f.pullValue);
      const display = f.display || f.pullValue;
      html += `<div class="flex items-center justify-between gap-2 rounded-lg border ${matches ? 'border-emerald-100' : 'border-slate-100'} px-2.5 py-1.5">
        <div><div class="text-xs text-slate-400 uppercase font-semibold">${f.label}</div><div>${escapeHtml(display)}</div></div>
        ${matches ? '<span class="badge badge-green">Matched</span>' : `<button type="button" data-pull="${f.key}" data-value="${escapeHtml(f.pullValue)}" class="text-xs font-semibold text-teal-700">${f.formValue ? 'Overwrite' : 'Pull'} &rarr;</button>`}
      </div>`;
    });
    html += '</div></div>';
    el.innerHTML = html;
    el.querySelectorAll('[data-pull]').forEach((btn) => {
      btn.addEventListener('click', () => {
        const key = btn.dataset.pull;
        const value = btn.dataset.value;
        form[key] = value;
        if (key === 'aadhaar') { aadhaarDisplay.value = maskAadhaar(value); }
        else { const inputEl = $('f_' + key); if (inputEl) inputEl.value = value; }
        renderUdiseResult(res);
      });
    });
  }

  // ---- Stepper ----
  function renderStepper() {
    const el = $('stepper');
    el.innerHTML = STEPS.map((s, i) => {
      const cls = i === currentStep ? 'current' : (i < currentStep ? 'complete' : 'pending');
      const line = i < STEPS.length - 1 ? `<div class="step-line ${i < currentStep ? 'complete' : ''}"></div>` : '';
      return `<div style="display:flex;align-items:center;flex:${i < STEPS.length - 1 ? 1 : 'none'}">
        <div style="display:flex;flex-direction:column;align-items:center;gap:.25rem">
          <div class="step-dot ${cls}" data-goto="${i}">${i < currentStep ? '&check;' : i + 1}</div>
          <div class="step-label ${i === currentStep ? 'current' : ''}">${s.label}</div>
        </div>${line}</div>`;
    }).join('');
    el.querySelectorAll('[data-goto]').forEach((d) => d.addEventListener('click', () => showStep(parseInt(d.dataset.goto, 10))));
  }
  function showStep(index) {
    currentStep = index;
    document.querySelectorAll('.wizard-step').forEach((s) => s.classList.toggle('active', parseInt(s.dataset.step, 10) === index));
    $('stepNumLabel').textContent = index + 1;
    $('btnBack').classList.toggle('hidden', index === 0);
    $('btnSaveNext').textContent = index === STEPS.length - 1 ? 'Save & Finish' : 'Save & Next';
    if (STEPS[index].id === 'bank') populateAccountHolder();
    if (STEPS[index].id === 'education' && form.school_awc === 'SCHOOL') ensureSchoolScopeUi();
    if (STEPS[index].id === 'review') renderReview();
    renderStepper();
    document.getElementById('wizardRoot').scrollIntoView({ behavior: 'smooth', block: 'start' });
  }
  $('btnBack').addEventListener('click', () => showStep(Math.max(0, currentStep - 1)));

  // ---- Review ----
  function renderReview() {
    const sections = [
      { title: 'Location & Identity', step: 0, rows: [
        ['CLRC', nameOf(MASTER.clrc, form.clrccode, 'clrccode', 'clrcname')],
        ['School / Cluster', nameOf(MASTER.clusters, form.clucd, 'clucd', 'cluname')],
      ] },
      { title: 'Personal Details', step: 1, rows: [
        ['CWSN Name', form.cwsn_name], ['Date of Birth', form.dob], ['Gender', form.gender],
        ["Father's Name", form.cwsn_f_name], ["Mother's Name", form.cwsn_m_name], ['Legal Guardian', form.legalgurdian],
        ['Aadhaar Number', form.aadhaar ? maskAadhaar(form.aadhaar) : ''], ['Contact Number', form.contact_no],
        ['Manabik Registered?', form.manabik_yn],
      ] },
      { title: 'Address', step: 2, rows: [['Address Line 1', form.add1], ['Address Line 2', form.add2], ['Address Line 3', form.add3], ['PIN Code', form.pin]] },
      { title: 'Disability & Support', step: 3, rows: [
        ['Disability Type', nameOf(MASTER.disabilities, form.disability_id, 'disability_id', 'disability_name')],
        ['Disability Certificate?', form.dis_certi_yn],
        ...(form.dis_certi_yn === 'YES' ? [['Certificate Valid?', form.dis_certi_valid_yn]] : []),
        ['Assistive Appliance', nameOf(MASTER.appliances, form.appliance_id, 'appliance_id', 'appliance_name')],
        ['Therapy Required?', form.therapy_reqd_yn],
        ...(form.therapy_reqd_yn === 'YES' ? [['Therapy Provided?', form.therapy_provide_yn]] : []),
        ['Special Educator', nameOf(MASTER.spledus, form.spledu_reg_no, 'regno', 'spl_edu_name')],
      ] },
      { title: 'Education Status', step: 4, rows: [
        ['Currently Enrolled?', form.in_school_yn],
        ...(form.in_school_yn === 'YES' ? [['School or AWC', form.school_awc]] : []),
        ...(form.school_awc === 'SCHOOL' ? [['School', $('f_schcd_display').value], ['Class', form.class]] : []),
        ...(form.school_awc === 'AWC' ? [['AWC', $('f_awc_no_display').value]] : []),
        ['Date of Entry', form.date_of_entry], ['PEN', form.pen],
      ] },
      { title: 'Bank Details', step: 5, rows: [
        ['IFSC Code', form.ifsc], ['Bank', nameOf(MASTER.banks, form.bank_id, 'bank_id', 'bank_name')],
        ['Branch Name', form.branch_name], ['MICR Code', form.micr], ['Account Number', form.acno], ['Account Holder Name', form.ac_holder],
      ] },
    ];
    const area = $('reviewArea');
    area.innerHTML = sections.map((sec) => `
      <div class="card p-4">
        <div class="flex items-center justify-between mb-2">
          <h3 class="text-sm font-bold text-slate-700 uppercase tracking-wide">${sec.title}</h3>
          <button type="button" class="text-xs text-blue-600" data-editstep="${sec.step}">Edit</button>
        </div>
        <div class="step-grid">${sec.rows.map(([l, v]) => `<div><div class="text-xs text-slate-400 uppercase font-semibold">${l}</div><div>${escapeHtml(v || '—')}</div></div>`).join('')}</div>
      </div>`).join('');
    area.querySelectorAll('[data-editstep]').forEach((b) => b.addEventListener('click', () => showStep(parseInt(b.dataset.editstep, 10))));

    $('printSubtitle').textContent = `CWSN Record Summary${savedCode ? ' — Code: ' + savedCode : ''} — Generated ${new Date().toLocaleDateString('en-GB')}`;
    $('printBody').innerHTML = sections.map((sec) => `
      <div class="print-form-section">
        <div class="print-form-section-title">${sec.title}</div>
        ${sec.rows.map(([l, v]) => `<div>${l} : <span class="print-form-value">${escapeHtml(v || '')}</span></div>`).join('')}
      </div>`).join('');
  }
  $('btnPrint').addEventListener('click', () => { if (savedCode) window.print(); });

  // ---- Save ----
  async function doSave(advance) {
    const btn = advance ? $('btnSaveNext') : $('btnSave');
    const orig = btn.textContent;
    btn.disabled = true; btn.textContent = 'Saving...';
    $('formError').classList.add('hidden');
    $('formSuccess').classList.add('hidden');
    try {
      // Any field genuinely NULL on the loaded record (e.g. an unresolved
      // bank_id from before this backfill existed) is JS `null` here, not
      // an empty string. URLSearchParams would otherwise stringify that as
      // the literal text "null" — sending real garbage instead of "blank" —
      // so normalize every null/undefined value to '' before it's sent.
      const payload = {};
      Object.keys(form).forEach((k) => { payload[k] = (form[k] === null || form[k] === undefined) ? '' : form[k]; });
      delete payload.schcat_id;
      if (savedCode) payload.cwsn_code = savedCode;
      const { status, json } = await apiPostForm('api/save_cwsn.php', payload);
      if (status !== 200 || json.error) {
        $('formError').textContent = json.error || 'Could not save the record.';
        $('formError').classList.remove('hidden');
        return;
      }
      savedCode = json.cwsn_code;
      showFieldErrors(json.errors);
      const badge = json.complete ? '<span class="badge badge-green">Complete</span>' : '<span class="badge badge-amber">Incomplete</span>';
      $('statusBadge').innerHTML = badge;
      $('btnPrint').disabled = false;
      $('btnPrint').removeAttribute('title');
      const successEl = $('formSuccess');
      successEl.className = 'rounded-lg border px-4 py-3 text-sm ' + (json.complete ? 'bg-emerald-50 border-emerald-200 text-emerald-700' : 'bg-amber-50 border-amber-200 text-amber-700');
      successEl.textContent = json.complete ? 'Saved — all sections complete.' : 'Saved as incomplete — pick up where you left off any time.';
      successEl.classList.remove('hidden');

      if (advance) {
        if (currentStep < STEPS.length - 1) showStep(currentStep + 1);
        else window.location.href = 'cwsn_list.php';
      }
    } catch (e) {
      $('formError').textContent = 'Network error — could not reach the server.';
      $('formError').classList.remove('hidden');
    } finally {
      btn.disabled = false; btn.textContent = orig;
    }
  }
  $('btnSave').addEventListener('click', () => doSave(false));
  $('btnSaveNext').addEventListener('click', () => doSave(true));

  // ---- Init ----
  function init() {
    bindSimpleFields();
    populateClusters();
    updateConditionals();
    if (INITIAL_SCHOOL_NAME) $('f_schcd_display').value = INITIAL_SCHOOL_NAME;
    if (INITIAL_AWC_NAME) $('f_awc_no_display').value = INITIAL_AWC_NAME;
    if (typeof INITIAL_SCHCAT_ID !== 'undefined' && INITIAL_SCHCAT_ID) { form.schcat_id = INITIAL_SCHCAT_ID; populateClasses(); }
    if (form.ifsc) {
      $('f_ifsc_display').value = form.ifsc;
      $('f_branch_name').value = form.branch_name || '';
      $('f_micr').value = form.micr || '';
      $('f_bank_id').value = form.bank_id || '';
    }
    if (form.bank_id) $('f_bank_display').value = nameOf(MASTER.banks, form.bank_id, 'bank_id', 'bank_name');
    showStep(0);
  }

  init();
})();
