// public/assets/app.js
document.addEventListener('DOMContentLoaded', () => {

  /* =================== VISIT COUNTERS (UI-only bump) =================== */
  // Server PHP already renders #countToday and #countAll correctly.
  // On successful save, just bump the DOM so user sees the change instantly.
  function bumpServerCounters(delta = 1) {
    const tEl = document.getElementById('countToday');
    const aEl = document.getElementById('countAll');
    const curT = parseInt((tEl?.textContent || '0'), 10) || 0;
    const curA = parseInt((aEl?.textContent || '0'), 10) || 0;
    if (tEl) tEl.textContent = String(curT + delta);
    if (aEl) aEl.textContent = String(curA + delta);
  }
  // =====================================================================


  const $  = (s,ctx=document)=>ctx.querySelector(s);
  const $$ = (s,ctx=document)=>Array.from(ctx.querySelectorAll(s));
  function normalizeUrl(u){
    if (!u) return '';
    // force https on https pages
    if (location.protocol === 'https:' && u.startsWith('http://')) {
      u = 'https://' + u.slice(7);
    }
    // ensure /sbm prefix when path starts with /public/...
    if (u.startsWith('/public/')) {
      u = '/sbm' + u;
    }
    return u;
  }

  // ---- MOBILE DEBUG HUD ----
  (function(){
    const bar = document.createElement('div');
    bar.id = 'mdbg';
    bar.style.cssText =
      'position:fixed;left:0;right:0;bottom:0;z-index:99999;background:#111;color:#0f0;' +
      'font:12px/1.4 monospace;padding:6px 8px;max-height:40vh;overflow:auto;opacity:.95';
    document.addEventListener('DOMContentLoaded', ()=>document.body.appendChild(bar));
    function log(msg){ try{
      const p=document.createElement('div'); p.textContent=String(msg);
      bar.appendChild(p);
    }catch(_){}
    }
    window.mdbg = log;
    window.addEventListener('error', e=>log('JS error: ' + (e.message||e)));
    window.addEventListener('unhandledrejection', e=>{
      const r = e.reason;
      log('Promise error: ' + (r && (r.message||r.stack||r)) );
    });
  })();


  function getGeo() {
    return new Promise((resolve) => {
      if (!navigator.geolocation) return resolve(null);
      navigator.geolocation.getCurrentPosition(
        pos => resolve({
          lat: pos.coords.latitude,
          lng: pos.coords.longitude,
          acc: pos.coords.accuracy
        }),
        () => resolve(null),
        { enableHighAccuracy: true, timeout: 9000, maximumAge: 0 }
      );
    });
  }
  function flagEmoji(cc) {
    if (!cc || cc.length!==2) return '';
    return String.fromCodePoint(...cc.toUpperCase().split('').map(c => 127397 + c.charCodeAt()));
  }
  async function reverseGeocode(lat, lng) {
    // Helper to safely read JSON
    async function fetchJson(url) {
      try {
        const r = await fetch(url);
        const j = await r.json();
        return { ok: true, json: j };
      } catch (err) {
        console.warn('fetchJson error', err, url);
        return { ok: false, err };
      }
    }

    const token = (window.APP_CFG && window.APP_CFG.MAPBOX_TOKEN) || '';
    const gkey  = (window.APP_CFG && window.APP_CFG.GOOGLE_KEY) || '';

    // ----- MAPBOX -----
    if (token) {
      try {
        const url = `https://api.mapbox.com/geocoding/v5/mapbox.places/${lng},${lat}.json?language=en&types=place,locality,neighborhood,district,region,country,address,postcode&access_token=${encodeURIComponent(token)}`;
        const { ok, json } = await fetchJson(url);
        if (ok && json && Array.isArray(json.features) && json.features.length) {
          const feat = json.features[0];
          const ctx = Array.isArray(feat.context) ? feat.context : [];

          const findText = (frags) => {
            for (const f of frags) {
              const fromFeat = json.features.find(x => (x.id||'').startsWith(f));
              if (fromFeat && fromFeat.text) return fromFeat.text;
              const fromCtx = ctx.find(x => (x.id||'').startsWith(f));
              if (fromCtx && fromCtx.text) return fromCtx.text;
            }
            return '';
          };

          const village = findText(['place', 'locality', 'neighborhood', 'address']) || '';
          const district = findText(['district', 'locality']) || '';
          const state = findText(['region']) || '';
          const country = findText(['country']) || '';
          let cc = '';
          const countryObj = ctx.find(x => (x.id||'').startsWith('country'));
          if (countryObj) {
            cc = countryObj.short_code || (countryObj.id||'').split('.').pop();
          }
          cc = cc ? cc.split('-').pop().toUpperCase() : '';

          let address = feat.place_name || '';
          if (!address && json.features.length) {
            const addrFeat = json.features.find(f => (f.place_type||[]).includes('address')) || json.features[0];
            address = addrFeat ? (addrFeat.place_name || '') : '';
          }

          return { village, district, state, country, cc, address };
        } else {
          console.debug('mapbox returned no features or empty result', json);
        }
      } catch (e) {
        console.warn('Mapbox reverseGeocode error', e);
      }
    }

    // ----- GOOGLE -----
    if (gkey) {
      try {
        const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${encodeURIComponent(gkey)}`;
        const { ok, json } = await fetchJson(url);
        if (ok && json && json.status === 'OK' && Array.isArray(json.results) && json.results.length) {
          const comps = json.results[0].address_components || [];
          const pick = (typeList) => {
            for (const t of typeList) {
              const c = comps.find(x => Array.isArray(x.types) && x.types.includes(t));
              if (c && c.long_name) return c.long_name;
            }
            return '';
          };

          const village = pick(['sublocality_level_1','sublocality','locality','neighborhood','administrative_area_level_3']);
          const district = pick(['administrative_area_level_2']);
          const state = pick(['administrative_area_level_1']);
          const country = pick(['country']);
          const cc = (comps.find(x => (x.types||[]).includes('country')) || {}).short_name || '';
          const address = json.results[0].formatted_address || '';

          return { village, district, state, country, cc, address };
        } else {
          console.debug('google geocode returned no results or non-OK status', json);
        }
      } catch (e) {
        console.warn('Google reverseGeocode error', e);
      }
    }

    // ----- FALLBACK: OSM Nominatim (no key) -----
    try {
      const url = `https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${encodeURIComponent(lat)}&lon=${encodeURIComponent(lng)}&addressdetails=1`;
      const { ok, json } = await fetchJson(url);
      if (ok && json && json.address) {
        const a = json.address || {};
        const village = a.village || a.hamlet || a.town || a.suburb || a.neighbourhood || a.city || '';
        const district = a.county || a.state_district || a.region || '';
        const state = a.state || '';
        const country = a.country || '';
        const cc = a.country_code ? a.country_code.toUpperCase() : '';
        const address = json.display_name || '';
        return { village, district, state, country, cc, address };
      } else {
        console.debug('nominatim returned no useful address', json);
      }
    } catch (e) {
      console.warn('Nominatim reverseGeocode error', e);
    }

    // final empty fallback
    return { village:'', district:'', state:'', country:'', cc:'', address:'' };
  }

  function drawStampBlock(ctx, canvas, lines) {
    // Configuration
    const pad = 12;
    const lineH = 20;
    const font = '14px Poppins, Arial, sans-serif';
    ctx.font = font;
    ctx.textBaseline = 'top';

    const maxBlockWidth = Math.min(canvas.width - 60, 680);
    const maxTextWidth = maxBlockWidth - pad * 2;

    const wrapLine = (text) => {
      if (!text) return [''];
      const words = String(text).split(/\s+/);
      const wrapped = [];
      let cur = '';
      for (let i = 0; i < words.length; i++) {
        const w = words[i];
        const test = cur ? (cur + ' ' + w) : w;
        const m = ctx.measureText(test).width;
        if (m <= maxTextWidth) {
          cur = test;
        } else {
          if (cur) wrapped.push(cur);
          if (ctx.measureText(w).width > maxTextWidth) {
            let part = '';
            for (let ch of w) {
              const tpart = part + ch;
              if (ctx.measureText(tpart).width <= maxTextWidth) {
                part = tpart;
              } else {
                if (part) wrapped.push(part);
                part = ch;
              }
            }
            if (part) cur = part; else cur = '';
          } else {
            cur = w;
          }
        }
      }
      if (cur) wrapped.push(cur);
      return wrapped;
    };

    const wrappedLines = [];
    for (let ln of lines) wrapLine(ln).forEach(x => wrappedLines.push(x));

    const widths = wrappedLines.map(l => ctx.measureText(l).width);
    const contentWidth = widths.length ? Math.max(...widths) : 0;
    const w = Math.min(Math.max(contentWidth + pad * 2, 200), maxBlockWidth);
    const h = lineH * wrappedLines.length + pad * 2;

    const x = pad;
    const y = canvas.height - h - pad;

    ctx.fillStyle = 'rgba(0,0,0,0.55)';
    ctx.fillRect(x, y, w, h);

    ctx.fillStyle = '#fff';
    wrappedLines.forEach((line, i) => {
      const ty = y + pad + i * lineH;
      let txt = line;
      if (ctx.measureText(txt).width > (w - pad * 2)) {
        while (txt.length > 0 && ctx.measureText(txt + '…').width > (w - pad * 2)) {
          txt = txt.slice(0, -1);
        }
        txt = txt + '…';
      }
      ctx.fillText(txt, x + pad, ty);
    });
  }

  function gmtOffsetString(date) {
    const m = -date.getTimezoneOffset();
    const sign = m >= 0 ? '+' : '-';
    const abs = Math.abs(m); const hh = String(Math.floor(abs/60)).padStart(2,'0'); const mm = String(abs%60).padStart(2,'0');
    return `GMT${sign}${hh}:${mm}`;
  }


  /* ---------- Top message helpers ---------- */
  function showTopMessage(text, isError = true) {
    const top = $('#top-error');
    if (!top) return;
    top.style.display = '';
    top.classList.remove('visible','success','error');
    top.classList.add('visible', isError ? 'error' : 'success');
    top.textContent = text;
    if (isError) setTimeout(()=>{ top.style.display='none'; top.classList.remove('visible','error'); }, 6000);
  }
  /* Put message OUTSIDE the button's flex row */
function ensureMessageRow(anchorEl) {
  if (!anchorEl) return null;

  // target row = button ka parent; message is row ke BAAD dalega
  const row = anchorEl.parentElement || anchorEl;
  let host = row.nextElementSibling;

  // Reuse if present
  if (!(host && host.classList && host.classList.contains('inline-msg-row'))) {
    host = document.createElement('div');
    host.className = 'inline-msg-row';
    row.insertAdjacentElement('afterend', host);
  }

  // Pure block row, full width; won't affect previous row (button row)
  host.style.cssText = `
    display:block;
    width:100%;
    margin-top:8px;
  `;
  return host;
}

function showInlineBanner(anchorEl, text, bg) {
  const host = ensureMessageRow(anchorEl);
  if (!host) return;

  // Create or reuse inner banner
  let box = host.querySelector('.inline-banner');
  if (!box) {
    box = document.createElement('div');
    box.className = 'inline-banner';
    host.appendChild(box);
  }

  // Clean, rectangular line (no effect on button)
  box.style.cssText = `
    background:${bg};
    color:#fff;
    padding:10px 14px;
    border-radius:8px;
    font-weight:600;
    font-size:14px;
    line-height:1.35;
    text-align:center;
    box-shadow:0 2px 8px rgba(0,0,0,.08);
  `;
  box.textContent = text || '';
  box.style.opacity = '1';
  clearTimeout(box._t);
  box._t = setTimeout(()=>{ box.style.transition='opacity .25s'; box.style.opacity='0'; }, bg === '#14532d' ? 3500 : 6000);
}

function showInlineSuccess(anchorEl, text) {
  showInlineBanner(anchorEl, text || 'Saved successfully', '#14532d');   // dark green
}
function showInlineError(anchorEl, text) {
  showInlineBanner(anchorEl, text || 'Something went wrong', '#b91c1c'); // dark red
}

/* Router: success -> inline green; error -> top red + inline red */
function showTopMessage(text, isError = true) {
  const anchorBtn = document.querySelector('#save-register, #save-training');

  if (!isError) {
    if (anchorBtn) showInlineSuccess(anchorBtn, text);
    const top = document.getElementById('top-error');
    if (top) { top.style.display='none'; top.classList.remove('visible','error','success'); }
    return;
  }

  const top = document.getElementById('top-error');
  if (top) {
    top.style.display = '';
    top.classList.remove('visible','success','error');
    top.classList.add('visible','error');
    top.textContent = text;
    setTimeout(()=>{ top.style.display='none'; top.classList.remove('visible','error'); }, 6000);
  }
  if (anchorBtn) showInlineError(anchorBtn, text);
}


  async function postFormAjax(form) {
    const action = form.getAttribute('action') || 'submit.php';
    const fd = new FormData(form);
    const res = await fetch(action, { method: 'POST', body: fd, credentials: 'same-origin' });
    const ct = (res.headers.get('content-type')||'').toLowerCase();
    if (ct.includes('application/json')) return res.json();
    const text = await res.text();
    try { return JSON.parse(text); } catch { return { success:false, message:text }; }
  }

  /* ---------- Phone availability hint (registration) ---------- */
  const phone = $('#phone'), phoneMsg = $('#phone-msg');
  if (phone) {
    let t;
    phone.addEventListener('input', ()=>{
      clearTimeout(t);
      if (phoneMsg) phoneMsg.textContent='';
      t = setTimeout(async ()=>{
        const v = phone.value.replace(/\D/g,'');
        if (v.length!==10) return;
        try {
          const res = await fetch('check_phone.php?phone='+v,{cache:'no-store'});
          const j = await res.json();
          if (j && j.success) phoneMsg.textContent = j.exists ? 'Phone already registered' : 'Phone available';
        } catch(e){}
      },400);
    });
  }

  /* ---------- Camera helper (reusable) ---------- */
  function setupCamera(openSel, takeSel, retakeSel, videoSel, canvasSel, previewSel, photoInputSel) {
    const openBtn = $(openSel), takeBtn = $(takeSel), retakeBtn = $(retakeSel);
    const video = $(videoSel), canvas = $(canvasSel), preview = $(previewSel), photoInput = $(photoInputSel);
    let stream = null;

    async function start() {
      if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) { alert('Camera not supported'); return; }
      try {
        stream = await navigator.mediaDevices.getUserMedia({video:{facingMode:'environment'}});
        if (video) { video.srcObject = stream; video.style.display='block'; video.play().catch(()=>{}); }
        if (takeBtn) takeBtn.style.display='';
        if (openBtn) openBtn.style.display='none';
      } catch (e) { alert('Camera error: '+(e.message||e)); }
    }
    function stop() {
      if (!stream) return;
      stream.getTracks().forEach(t=>t.stop());
      stream=null;
      if (video) { video.pause(); video.srcObject=null; video.style.display='none'; }
      if (openBtn) openBtn.style.display='';
    }
    async function snap() {
      if (!video || !canvas) return;

      // draw current frame
      canvas.width = video.videoWidth || 1280;
      canvas.height = video.videoHeight || 720;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

      // capture geo + reverse geocode (coords-only to avoid CORS)
      const geo = await getGeo();
      let lat=null, lng=null, acc=null;
      let where = {village:'', district:'', state:'', country:'', cc:'', address:''};

      if (geo) {
        lat = geo.lat; 
        lng = geo.lng; 
        acc = geo.acc;
        where.address = `Lat ${lat.toFixed(6)}, Lng ${lng.toFixed(6)}`;
      } else {
        where.address = 'Location unavailable';
      }

      // format time
      const now = new Date();
      const dateStr = now.toLocaleDateString('en-IN');
      const timeStr = now.toLocaleTimeString('en-IN', { hour12:true });
      const gmtStr  = gmtOffsetString(now);
      const flag    = where.cc ? (' ' + flagEmoji(where.cc)) : '';

      // 4 lines block
      const line1 = `${where.village || '—'}, ${where.district || '—'}, ${where.state || '—'}, ${where.country || '—'}${flag}`;
      const line2 = where.address || 'Address unavailable';
      const line3 = (lat && lng) ? `Lat ${lat.toFixed(6)}  Long ${lng.toFixed(6)}` : 'Lat/Long unavailable';
      const line4 = `${dateStr}, ${timeStr}, ${gmtStr}`;

      drawStampBlock(ctx, canvas, [line1, line2, line3, line4]);

      // export and preview
      const data = canvas.toDataURL('image/jpeg', 0.9);
      if (photoInput) photoInput.value = data;
      if (preview)   preview.innerHTML = `<img src="${data}" style="max-width:320px;border-radius:8px">`;

      // push hidden fields (both pages supported)
      const set = (id, val) => { const el = document.getElementById(id); if (el) el.value = val; };
      set('captured_at', now.toISOString());  set('captured_at_off', now.toISOString());
      if (lat!=null && lng!=null) {
        set('geo_lat', lat); set('geo_lng', lng); set('geo_acc', acc||'');
        set('geo_lat_off', lat); set('geo_lng_off', lng); set('geo_acc_off', acc||'');
      }
      set('geo_addr', where.address);  set('geo_addr_off', where.address);
      set('geo_village', where.village); set('geo_district', where.district);
      set('geo_state', where.state);     set('geo_country', where.country); set('geo_cc', where.cc);
      set('geo_village_off', where.village); set('geo_district_off', where.district);
      set('geo_state_off', where.state);     set('geo_country_off', where.country); set('geo_cc_off', where.cc);

      // stop camera & toggle buttons
      stop();
      if (takeBtn)   takeBtn.style.display='none';
      if (retakeBtn) retakeBtn.style.display='';
    }

    function retake() {
      if (preview) preview.innerHTML='';
      if (photoInput) photoInput.value='';
      if (retakeBtn) retakeBtn.style.display='none';
      start();
    }
    if (openBtn)  openBtn.addEventListener('click', start);
    if (takeBtn)  takeBtn.addEventListener('click', snap);
    if (retakeBtn)retakeBtn.addEventListener('click', retake);
  }

  // registration camera
  if ($('#open-camera')) {
    setupCamera('#open-camera','#take-photo','#retake-photo','#video','#canvas','#photo-preview','#photo_data');
  }
  // officer camera
  if ($('#open-camera-off')) {
    setupCamera('#open-camera-off','#take-photo-off','#retake-photo-off','#video','#canvas','#photo-preview-off','#photo_data_off');
  }

  /* ---------- Registration: explicit save (AJAX, no redirect) ---------- */
  {
    const regForm = $('#reg-form');
    const regBtn  = $('#save-register');
    if (regForm && regBtn) {
      regBtn.addEventListener('click', async () => {
        const ward  = $('#ward')?.value || '';
        const house = $('#house_no')?.value || '';
        const name  = $('#name')?.value || '';
        const phonev= ($('#phone')?.value||'').replace(/\D/g,'');
        const waste = $$('input[name="waste_segregation"]:checked').length;
        const d2d   = $$('input[name="door_to_door"]:checked').length;
        const photo = $('#photo_data')?.value || '';
        const date  = $('#date')?.value || '';
        const time  = $('#time')?.value || '';

        if (!date || !time || !ward || !house || !name || phonev.length!==10 || waste===0 || d2d===0 || !photo) {
          showTopMessage('Please fill all required fields (including date/time) and take photo.', true);
          return;
        }

        regBtn.disabled = true; regBtn.textContent = 'Saving...';
        try {
          const resp = await postFormAjax(regForm);
          if (resp && (resp.success || resp.ok)) {

            let msg = resp.message;
            if (!msg) {
              const tn = resp.training_number || resp.next_training_number || $('#training_number')?.value;
              msg = tn ? `Training ${tn} data has been submitted` : 'Training data has been submitted';
            }
            showTopMessage(msg, false);

            // ✅ UI counters +1 (server truth will align on next load)
            try { bumpServerCounters(1); } catch(e){ console.warn(e); }

            // optional: setTimeout(()=> location.reload(), 1200);
            regBtn.disabled = false; regBtn.textContent = 'Save Training';
          } else {
            showTopMessage(resp?.message || 'Save failed', true);
            regBtn.disabled = false; regBtn.textContent = 'Save Training';
          }
        } catch (e) {
          console.error(e);
          showTopMessage('Submission failed. Check console.', true);
          regBtn.disabled = false; regBtn.textContent = 'Save Training';
        }
      });
    }
  }

  /* ---------- Officer: lookup & render (robust) ---------- */
  (() => {
    const btn     = document.querySelector('#lookup');
    const phoneEl = document.querySelector('#lookup_phone');
    const form    = document.querySelector('#lookup-form'); // may be null
    if (!btn || !phoneEl) {
      window.mdbg && mdbg('Lookup wiring failed: #lookup or #lookup_phone not found');
      return;
    }

    btn.setAttribute('type', 'button');

    // Styled alert
    function showBizormAlert(message, okCallback) {
      if (document.getElementById('bizorm-alert-backdrop')) return;

      const backdrop = document.createElement('div');
      backdrop.id = 'bizorm-alert-backdrop';
      backdrop.style.cssText =
        'position:fixed;left:0;top:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center;' +
        'background:rgba(0,0,0,0.45);z-index:99999;';

      const box = document.createElement('div');
      box.style.cssText =
        'background:#241b1c;color:#fff;border-radius:12px;padding:22px 26px;min-width:320px;max-width:90%;' +
        'box-shadow:0 6px 24px rgba(0,0,0,0.5);font-family:inherit;text-align:center;';
      box.innerHTML = `
        <div style="font-weight:600;margin-bottom:10px;font-size:16px;">bizorm.com says</div>
        <div style="margin-bottom:20px;color:#f0f0f0;font-size:15px;">${message}</div>
        <button id="bizorm-alert-ok" style="
          background:#ff9ac9;border:none;border-radius:24px;padding:8px 24px;
          font-weight:600;font-size:15px;cursor:pointer;color:#000;">OK</button>
      `;

      backdrop.appendChild(box);
      document.body.appendChild(backdrop);

      const okBtn = document.getElementById('bizorm-alert-ok');
      okBtn.focus();
      const close = () => {
        if (backdrop.parentNode) backdrop.parentNode.removeChild(backdrop);
        document.removeEventListener('keydown', escHandler);
        if (typeof okCallback === 'function') okCallback();
      };
      okBtn.addEventListener('click', close);
      const escHandler = e => { if (e.key === 'Escape') close(); };
      document.addEventListener('keydown', escHandler);
    }

    // Safe JSON parser
    const safeJson = async (res) => {
      const text = await res.text();
      try { return { ok: true, data: JSON.parse(text) }; }
      catch (e) { return { ok: false, text, err: e }; }
    };

    async function doLookup() {
      const p = (phoneEl.value || '').replace(/\D/g, '');
      if (p.length !== 10) { alert('Enter 10 digit phone'); return; }

      try {
        const url = 'public_lookup.php?phone=' + p;
        const res = await fetch(url, { cache: 'no-store', credentials: 'same-origin' });
        const parsed = await safeJson(res);
        if (!parsed.ok) { alert('Server did not return JSON.'); return; }
        const j = parsed.data;

        // Not found
        if (!j || !j.found) {
          showBizormAlert('Resident not found', function() {
            const newBtn = btn.cloneNode(true);
            newBtn.textContent = 'New Registration';
            newBtn.addEventListener('click', function() { window.location.href = 'index.php'; });
            btn.parentNode.replaceChild(newBtn, btn);
          });
          return;
        }

        // Found
        const show = (sel, val) => { const el = document.querySelector(sel); if (el) el.textContent = val || ''; };
        const showImg = (sel, path) => {
          const el = document.querySelector(sel);
          if (!el) return;
          if (!path) { el.innerHTML=''; return; }
          let u = path;
          if (location.protocol === 'https:' && /^http:\/\//i.test(u)) u = 'https://' + u.slice(7);
          if (u.startsWith('/public/')) u = '/sbm' + u;
          el.innerHTML = `<img src="${u}" style="max-width:220px;border-radius:8px">`;
        };

        const box = document.querySelector('#resident-data');
        if (box) box.style.display = '';

        show('#r_ward', j.data.ward);
        show('#r_d2d',   j.data.door_to_door);
        show('#r_house_no', j.data.house_no);
        show('#r_name', j.data.name);
        show('#r_phone', j.data.phone);
        show('#r_waste', j.data.waste_segregation);
        showImg('#reg-photo', j.data.photo_path);

        const prev = document.querySelector('#previous-trainings');
        if (prev) prev.innerHTML = '';
        if (Array.isArray(j.trainings)) {
          j.trainings.forEach(t => {
            const d = document.createElement('div');
            const num = Number(t.training_number);
            const label = (num===1 ? 'Training First' : num===2 ? 'Training Second' : 'Training Third');
            let u = t.photo_path || '';
            if (u) {
              if (location.protocol === 'https:' && /^http:\/\//i.test(u)) u = 'https://' + u.slice(7);
              if (u.startsWith('/public/')) u = '/sbm' + u;
            }
            d.innerHTML = `
              <strong>${label}</strong>
              <div>Date: ${t.training_date || ''}</div>
              <div>WS: ${t.waste_segregation || ''}</div>
              <div>DTDC: ${t.door_to_door || ''}</div>  
              <div style="margin-top:6px">${u ? `<img src="${u}" style="max-width:220px;border-radius:6px">` : ''}</div>
              <hr>`;
            prev.appendChild(d);
          });
        }

        const init = document.querySelector('#initial-block');
        if (init) {
          const hasT1 = (j.trainings || []).some(t => Number(t.training_number) === 1);
          init.style.display = hasT1 ? 'none' : '';
        }

        const nlab = document.querySelector('#next-training-label');
        if (nlab) nlab.textContent = j.next_training_label || 'Training';

        const nextSec = document.querySelector('#next-training-section');
        if (j.next_training_number === null || j.data.trainings_completed >= 3) {
          if (nextSec) nextSec.style.display = 'none';
        } else {
          if (nextSec) nextSec.style.display = '';
          const rid = document.querySelector('#resident_id');
          if (rid) rid.value = j.data.id;
          const pp = document.querySelector('#photo-preview-off');
          if (pp) pp.innerHTML = '';
          const pi = document.querySelector('#photo_data_off');
          if (pi) pi.value = '';
          document.querySelectorAll('#next-training-section input[name="waste_segregation"]').forEach(r=>r.checked=false);
          document.querySelectorAll('#next-training-section input[name="door_to_door"]').forEach(r=>r.checked=false);
          const d = new Date();
          const rdate = document.querySelector('#r_date');
          const rtime = document.querySelector('#r_time');
          if (rdate) rdate.value = d.toISOString().slice(0,10);
          if (rtime) rtime.value = d.toTimeString().slice(0,5);
        }

      } catch (e) {
        console.error('Lookup failed', e);
        alert('Lookup failed (check console).');
      }
    }

    btn.addEventListener('click', e => { e.preventDefault(); doLookup(); });
    form && form.addEventListener('submit', e => { e.preventDefault(); doLookup(); });

    window.mdbg && mdbg('Lookup wiring ready');
  })();


  /* ---------- Officer: explicit save button (no redirect) ---------- */
  {
    const offForm = $('#officer-form');
    const offBtn  = $('#save-training');
    if (offForm && offBtn) {
      offBtn.addEventListener('click', async ()=>{
        const rid   = $('#resident_id')?.value || '';
        const photo = $('#photo_data_off')?.value || '';
        const waste = $$('#next-training-section input[name="waste_segregation"]:checked').length;
        const d2d   = $$('#next-training-section input[name="door_to_door"]:checked').length;
        const d = $('#r_date')?.value || '', t = $('#r_time')?.value || '';

        if (!rid) { showTopMessage('Please lookup a resident first.', true); return; }
        if (!d || !t) { showTopMessage('Please set date/time.', true); return; }
        if (waste===0) { showTopMessage('Please choose waste segregation.', true); return; }
        if (d2d===0)   { showTopMessage('Please choose Door to Door Collection.', true); return; }
        if (!photo) { showTopMessage('Please capture photo for this visit.', true); return; }

        offBtn.disabled = true; offBtn.textContent = 'Saving...';
        try{
          const resp = await postFormAjax(offForm);
          if (resp && resp.success) {
            showTopMessage(resp.message || 'Saved', false);

            // ✅ UI counters +1 immediately
            try { bumpServerCounters(1); } catch(e){ console.warn(e); }

            setTimeout(()=> location.reload(), 1200);
          } else {
            showTopMessage(resp?.message || 'Save failed', true);
            offBtn.disabled = false; offBtn.textContent = 'Save Training';
          }
        }catch(err){
          console.error(err);
          showTopMessage('Submission failed. Check console.', true);
          offBtn.disabled = false; offBtn.textContent = 'Save Training';
        }
      });
    }
  }

  /* ---------- init: hide empty error boxes ---------- */
  $$('.error').forEach(el => { el.style.display = 'none'; });
});
