// assets/js/fitur_baru.js
// Modul 3 Fitur Baru WebGIS Bansos
// Integrasi dengan App (app.js) yang sudah ada.
// Cara pakai: <script src="assets/js/fitur_baru.js"></script> SETELAH app.js

const FiturBaru = (() => {

  /* ══════════════════════════════════════════════════
     SHARED HELPERS
  ══════════════════════════════════════════════════ */
  function svgIcon(paths, w = 14, h = 14) {
    return `<svg viewBox="0 0 24 24" width="${w}" height="${h}" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">${paths}</svg>`;
  }

  const ICONS = {
    swap:    `<path d="M7 16V4m0 0L3 8m4-4 4 4"/><path d="M17 8v12m0 0 4-4m-4 4-4-4"/>`,
    shield:  `<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>`,
    trend:   `<polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/>`,
    clock:   `<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>`,
    check2:  `<polyline points="20 6 9 17 4 12"/>`,
    alert:   `<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>`,
    gear:    `<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>`,
    exit:    `<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/>`,
    chart:   `<line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/>`,
    refresh: `<polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/>`,
  };

  function formatRp(n) {
    return 'Rp ' + parseInt(n || 0).toLocaleString('id-ID');
  }

  function toast(msg, type = 'info') {
    // reuse toast dari app.js jika ada
    if (window.App && typeof App.showToast === 'function') {
      App.showToast(msg, type);
    } else {
      const c = document.getElementById('toast-container');
      if (!c) return;
      const t = document.createElement('div');
      t.className = `toast ${type}`;
      t.textContent = msg;
      c.appendChild(t);
      setTimeout(() => { t.style.opacity = '0'; setTimeout(() => t.remove(), 250); }, 3500);
    }
  }

  function showModal(id) { document.getElementById(id)?.classList.add('show'); }
  function closeModal(id) { document.getElementById(id)?.classList.remove('show'); }

  /* ══════════════════════════════════════════════════
     ░░ FITUR 1: REDISTRIBUSI BANTUAN ░░
  ══════════════════════════════════════════════════ */
  const Redistribusi = (() => {
    let analisisData = null;
    let saranData    = [];

    const BEBAN_CONFIG = {
      kosong:  { label: 'Kosong',   color: '#94a3b8', bg: 'rgba(148,163,184,0.12)' },
      ringan:  { label: 'Ringan',   color: '#10b981', bg: 'rgba(16,185,129,0.12)'  },
      normal:  { label: 'Normal',   color: '#6366f1', bg: 'rgba(99,102,241,0.12)'  },
      padat:   { label: 'Padat',    color: '#f59e0b', bg: 'rgba(245,158,11,0.12)'  },
      overload:{ label: 'Overload', color: '#ef4444', bg: 'rgba(239,68,68,0.12)'   },
    };

    const PRIORITAS_CONFIG = {
      tinggi: { label: 'Prioritas Tinggi', cls: 'badge-sangat-miskin' },
      sedang: { label: 'Prioritas Sedang', cls: 'badge-miskin'        },
      rendah: { label: 'Prioritas Rendah', cls: 'badge-rentan-miskin' },
    };

    async function loadAnalisis() {
      const container = document.getElementById('redistribusi-analisis');
      if (!container) return;
      container.innerHTML = `<div class="fb-loading">${svgIcon(ICONS.refresh, 18, 18)}<span>Menganalisis beban distribusi...</span></div>`;
      const summaryContainer = document.getElementById('redistribusi-summary-container');
      if (summaryContainer) summaryContainer.innerHTML = '';

      try {
        const res  = await fetch('api/redistribusi.php?action=analisis');
        const json = await res.json();
        if (!json.success) throw new Error(json.message);

        analisisData = json.data;
        saranData    = json.saran;
        renderAnalisis(json.data, json.summary);
        renderSaran(json.saran);
        renderRiwayat();
      } catch (e) {
        container.innerHTML = `<div class="fb-error">${svgIcon(ICONS.alert,16,16)} Gagal memuat: ${e.message}</div>`;
      }
    }

    let cachedSummaryHtml = '';

    function renderAnalisis(data, summary) {
      const container = document.getElementById('redistribusi-analisis');
      if (!container) return;

      if (summary) {
        const summaryContainer = document.getElementById('redistribusi-summary-container');
        if (summaryContainer) {
          summaryContainer.innerHTML = `
            <div class="redistribusi-summary">
              ${Object.entries(summary).filter(([k]) => k !== 'total_ibadah').map(([k, v]) => {
                const cfg = BEBAN_CONFIG[k] || { color: '#64748b', bg: 'rgba(100,116,139,0.1)' };
                return `<div class="redist-sum-item" style="background:${cfg.bg};border-color:${cfg.color}20">
                  <span class="redist-sum-val" style="color:${cfg.color}">${v}</span>
                  <span class="redist-sum-key">${cfg.label || k}</span>
                </div>`;
              }).join('')}
            </div>`;
        }
      }

      // Filter locally based on search
      const searchVal = document.getElementById('redistribusi-search')?.value.toLowerCase() || '';
      const filtered = data ? data.filter(d => {
        return !searchVal || 
               d.ibadah.nama.toLowerCase().includes(searchVal) ||
               (d.ibadah.kelurahan || '').toLowerCase().includes(searchVal) ||
               (d.ibadah.kecamatan || '').toLowerCase().includes(searchVal);
      }) : [];

      const cardsHtml = filtered.map(d => {
        const cfg  = BEBAN_CONFIG[d.status_beban] || BEBAN_CONFIG.normal;
        const pct  = Math.min(d.pct_beban, 100);
        return `<div class="redist-card" style="border-left:3px solid ${cfg.color}">
          <div class="redist-card-header">
            <div>
              <div class="redist-card-nama">${d.ibadah.nama}</div>
              <div class="redist-card-sub">${d.ibadah.kelurahan || ''} ${d.ibadah.kecamatan ? '· ' + d.ibadah.kecamatan : ''}</div>
            </div>
            <span class="fb-badge" style="background:${cfg.bg};color:${cfg.color}">${cfg.label}</span>
          </div>
          <div class="redist-progress-wrap">
            <div class="redist-progress-bar">
              <div class="redist-progress-fill" style="width:${pct}%;background:${cfg.color}"></div>
            </div>
            <span class="redist-progress-pct">${d.pct_beban}%</span>
          </div>
          <div class="redist-stat-row">
            <div class="redist-stat-item">
              <span class="redist-stat-val" style="color:#f87171">${d.sangat_miskin}</span>
              <span class="redist-stat-key">Sangat Miskin</span>
            </div>
            <div class="redist-stat-item">
              <span class="redist-stat-val" style="color:#6366f1">${d.miskin}</span>
              <span class="redist-stat-key">Miskin</span>
            </div>
            <div class="redist-stat-item">
              <span class="redist-stat-val" style="color:#fbbf24">${d.rentan_miskin}</span>
              <span class="redist-stat-key">Rentan</span>
            </div>
            <div class="redist-stat-item">
              <span class="redist-stat-val">${d.total_warga}/${d.kapasitas}</span>
              <span class="redist-stat-key">KK/Kap.</span>
            </div>
          </div>
          <div style="font-size:10px;color:var(--text-muted);margin-top:4px">
            Rasio kemiskinan: <b>${d.rasio_miskin}%</b>
            ${d.surplus_kapasitas > 0 ? `· Surplus: <b style="color:#10b981">+${d.surplus_kapasitas} KK</b>` : ''}
            ${d.defisit_kapasitas > 0 ? `· Defisit: <b style="color:#ef4444">-${d.defisit_kapasitas} KK</b>` : ''}
          </div>
        </div>`;
      }).join('');

      container.innerHTML = cardsHtml;
    }

    function renderSearch() {
      renderAnalisis(analisisData, null);
    }

    function renderSaran(saran) {
      const container = document.getElementById('redistribusi-saran');
      if (!container) return;

      if (!saran.length) {
        container.innerHTML = `<div class="fb-empty">${svgIcon(ICONS.check2,20,20)}<div>Distribusi sudah merata. Tidak ada saran redistribusi saat ini.</div></div>`;
        return;
      }

      container.innerHTML = saran.map((s, i) => {
        const priCfg = PRIORITAS_CONFIG[s.prioritas] || PRIORITAS_CONFIG.rendah;
        return `<div class="saran-card">
          <div class="saran-card-header">
            <span class="fb-badge ${priCfg.cls}">${priCfg.label}</span>
            <span style="font-size:10px;color:var(--text-muted)">${s.jarak_km} km</span>
          </div>
          <div class="saran-flow">
            <div class="saran-ibadah surplus">${svgIcon(ICONS.swap,12,12)} ${s.pengirim_nama}</div>
            <div class="saran-arrow">→ ${s.jumlah_kk} KK →</div>
            <div class="saran-ibadah defisit">${s.penerima_nama} ${svgIcon(ICONS.alert,12,12)}</div>
          </div>
          <div class="saran-alasan">${s.alasan}</div>
          <div style="font-size:10px;color:var(--text-muted);margin:4px 0">Est. dana: <b>${formatRp(s.estimasi_dana)}/bulan</b></div>
          <div class="saran-actions">
            <button class="btn btn-primary btn-xs" onclick="FiturBaru.Redistribusi.setujuiSaran(${i})">
              ${svgIcon(ICONS.check2,11,11)} Setujui & Simpan
            </button>
            <button class="btn btn-ghost btn-xs" onclick="FiturBaru.Redistribusi.tolakSaran(${i})">Tolak</button>
          </div>
        </div>`;
      }).join('');
    }

    async function renderRiwayat() {
      const container = document.getElementById('redistribusi-riwayat');
      if (!container) return;
      try {
        const res  = await fetch('api/redistribusi.php?action=riwayat&limit=10');
        const json = await res.json();
        if (!json.data.length) {
          container.innerHTML = `<div class="fb-empty" style="padding:20px">Belum ada riwayat redistribusi</div>`;
          return;
        }
        const STATUS_LABEL = { saran_sistem:'Saran Sistem', disetujui:'Disetujui', ditolak:'Ditolak', selesai:'Selesai' };
        const STATUS_CLS   = { saran_sistem:'badge-belum-terima', disetujui:'badge-sudah-terima', ditolak:'badge-sangat-miskin', selesai:'badge-bantuan-rutin' };
        container.innerHTML = json.data.map(r => `
          <div class="riwayat-item">
            <div style="display:flex;justify-content:space-between;align-items:flex-start;gap:8px">
              <div>
                <div style="font-size:11px;font-weight:600;color:var(--text-primary)">${r.pengirim_nama} → ${r.penerima_nama}</div>
                <div style="font-size:10px;color:var(--text-muted);margin-top:2px">${r.jumlah_kk} KK · ${formatRp(r.estimasi_dana)}/bln · ${r.periode_bulan || ''}</div>
              </div>
              <span class="badge ${STATUS_CLS[r.status] || ''}">${STATUS_LABEL[r.status] || r.status}</span>
            </div>
            ${r.catatan_admin ? `<div style="font-size:10px;color:var(--text-muted);margin-top:4px;border-left:2px solid var(--border);padding-left:6px">${r.catatan_admin}</div>` : ''}
          </div>`).join('');
      } catch { container.innerHTML = `<div class="fb-error">Gagal memuat riwayat</div>`; }
    }

    async function setujuiSaran(idx) {
      const s = saranData[idx];
      if (!s) return;
      
      document.getElementById('sr-penerima-nama').textContent = s.penerima_nama;
      document.getElementById('sr-penerima-id').value = s.penerima_id;
      document.getElementById('sr-catatan-sistem').value = s.alasan;
      
      // Hitung rasio estimasi dana per KK dari saran (jika ada)
      const danaPerKK = s.jumlah_kk > 0 ? (s.estimasi_dana / s.jumlah_kk) : 200000;
      document.getElementById('sr-estimasi-dana-per-kk').value = danaPerKK;
      
      // Populate select dengan rumah ibadah yang surplus (kosong/ringan)
      const select = document.getElementById('sr-pengirim-id');
      const surplusList = analisisData.filter(d => d.status_beban === 'kosong' || d.status_beban === 'ringan');
      
      select.innerHTML = surplusList.map(d => {
        const selected = d.ibadah.id == s.pengirim_id ? 'selected' : '';
        return `<option value="${d.ibadah.id}" data-surplus="${d.surplus_kapasitas}" ${selected}>${d.ibadah.nama} (Surplus: ${d.surplus_kapasitas} KK)</option>`;
      }).join('');
      
      // Jika saran pengirim tidak ada di list surplus (mungkin list kosong), tambahkan manual
      if (select.innerHTML === '') {
        select.innerHTML = `<option value="${s.pengirim_id}" selected>${s.pengirim_nama}</option>`;
      }
      
      // Get eligible warga: dikelola_oleh_ibadah_id == penerima_id or (null and in radius)
      const container = document.getElementById('sr-warga-list-container');
      container.innerHTML = '<div style="text-align:center; padding:10px; color:#94a3b8">Memuat warga...</div>';
      
      const ibadahData = window.App ? window.App.getIbadahData() : [];
      const wargaData = window.App ? window.App.getWargaData() : [];
      const haversine = window.App ? window.App.haversine : null;

      const penerimaNode = ibadahData.find(i => parseInt(i.id) === parseInt(s.penerima_id));
      const pLat = parseFloat(penerimaNode?.latitude || 0);
      const pLng = parseFloat(penerimaNode?.longitude || 0);
      const pRad = parseFloat(penerimaNode?.radius_primer || 500);
      
      let eligibleWarga = wargaData.filter(w => {
        if (!['sangat_miskin', 'miskin', 'rentan_miskin'].includes(w.kategori_kemiskinan) || w.status_kemandirian === 'mandiri') return false;
        
        if (w.dikelola_oleh_ibadah_id && parseInt(w.dikelola_oleh_ibadah_id) === parseInt(s.penerima_id)) return true;
        if (!w.dikelola_oleh_ibadah_id && typeof haversine === 'function') {
          const dist = haversine(parseFloat(w.latitude), parseFloat(w.longitude), pLat, pLng);
          if (dist <= pRad) return true;
        }
        return false;
      });

      if (eligibleWarga.length === 0) {
        container.innerHTML = '<div style="text-align:center; padding:10px; color:#94a3b8">Tidak ada warga eligible yang dapat dipindahkan.</div>';
      } else {
        // Render checkboxes
        let html = '';
        eligibleWarga.forEach((w, idx) => {
          const checked = idx < s.jumlah_kk ? 'checked' : '';
          html += `
            <div style="display:flex; align-items:center; gap:8px; padding:6px 0; border-bottom:1px solid #f1f5f9;">
              <input type="checkbox" id="sr-warga-${w.id}" class="sr-warga-cb" value="${w.id}" ${checked} style="cursor:pointer">
              <label for="sr-warga-${w.id}" style="cursor:pointer; flex:1; margin:0;">
                <div style="font-weight:600; color:#334155">${w.nama_kepala_keluarga}</div>
                <div style="color:#64748b; font-size:10px;">${w.alamat || 'Alamat tidak diketahui'}</div>
              </label>
            </div>
          `;
        });
        container.innerHTML = html;
        
        // Add event listeners to update count
        const cbs = container.querySelectorAll('.sr-warga-cb');
        cbs.forEach(cb => {
          cb.addEventListener('change', () => {
            const count = container.querySelectorAll('.sr-warga-cb:checked').length;
            const inputJml = document.getElementById('sr-jumlah-kk');
            inputJml.value = count;
            const total = count * danaPerKK;
            document.getElementById('sr-estimasi-dana').value = total;
            document.getElementById('sr-estimasi-dana-display').value = formatRp(total);
          });
        });
      }

      const inputJml = document.getElementById('sr-jumlah-kk');
      const initialChecked = container.querySelectorAll('.sr-warga-cb:checked').length;
      inputJml.value = initialChecked;
      
      const total = initialChecked * danaPerKK;
      document.getElementById('sr-estimasi-dana').value = total;
      document.getElementById('sr-estimasi-dana-display').value = formatRp(total);
      
      document.getElementById('sr-catatan').value = '';
      showModal('modal-setujui-redistribusi');
    }

    async function submitSetujui() {
      const pengirimId = document.getElementById('sr-pengirim-id').value;
      const penerimaId = document.getElementById('sr-penerima-id').value;
      const jumlahKK   = document.getElementById('sr-jumlah-kk').value;
      const estimasi   = document.getElementById('sr-estimasi-dana').value;
      const catatan    = document.getElementById('sr-catatan').value.trim();
      const alasan     = document.getElementById('sr-catatan-sistem').value;
      
      if (!pengirimId || !jumlahKK || parseInt(jumlahKK) < 1) {
        toast('Lengkapi data redistribusi', 'error');
        return;
      }
      
      // Kumpulkan warga yang dipilih (sebelum disable button)
      const cbWarga = document.querySelectorAll('.sr-warga-cb:checked');
      const wargaIds = Array.from(cbWarga).map(cb => cb.value);
      
      const btn = document.querySelector('#modal-setujui-redistribusi .btn-primary');
      const oldHtml = btn.innerHTML;
      btn.innerHTML = '<div class="spinner"></div> Menyimpan...';
      btn.disabled = true;

      try {
        const res = await fetch('api/redistribusi.php', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            pengirim_id:    pengirimId,
            penerima_id:    penerimaId,
            jumlah_kk:      jumlahKK,
            estimasi_dana:  estimasi,
            status:         'disetujui',
            catatan_sistem: alasan,
            catatan_admin:  catatan,
            periode_bulan:  new Date().toLocaleDateString('en-CA').slice(0, 7),
            warga_ids:      wargaIds,
          }),
        });
        
        let json;
        try { json = await res.json(); } catch(e) {}
        
        if (!res.ok || (json && !json.success)) {
          throw new Error(json?.message || 'Gagal menyimpan redistribusi');
        }
        toast('Redistribusi disetujui dan disimpan', 'success');
        closeModal('modal-setujui-redistribusi');
        loadAnalisis();
        if (window.App && window.App.loadWarga) window.App.loadWarga();
      } catch (err) { 
        toast(err.message || 'Gagal menyimpan keputusan', 'error'); 
      } finally {
        btn.innerHTML = oldHtml;
        btn.disabled = false;
      }
    }

    async function tolakSaran(idx) {
      const s = saranData[idx];
      if (!s) return;
      const catatan = prompt('Alasan penolakan:') ?? 'Ditolak admin';
      try {
        await fetch('api/redistribusi.php', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            pengirim_id:   s.pengirim_id,
            penerima_id:   s.penerima_id,
            jumlah_kk:     s.jumlah_kk,
            estimasi_dana: s.estimasi_dana,
            status:        'ditolak',
            catatan_sistem:s.alasan,
            catatan_admin: catatan,
            periode_bulan: new Date().toLocaleDateString('en-CA').slice(0, 7),
          }),
        });
        toast('Saran ditolak dan dicatat', 'info');
        loadAnalisis();
      } catch { toast('Gagal menyimpan', 'error'); }
    }

    return { load: loadAnalisis, renderSearch, setujuiSaran, submitSetujui, tolakSaran, open: () => { showModal('modal-premium-redistribusi'); loadAnalisis(); } };
  })();

  /* ══════════════════════════════════════════════════
     ░░ FITUR 2: KETERBARUAN DATA ░░
  ══════════════════════════════════════════════════ */
  const Verifikasi = (() => {
    let konfig = {};

    const STATUS_CFG = {
      terverifikasi: { label: 'Terverifikasi', color: '#10b981', bg: 'rgba(16,185,129,0.12)' },
      perlu_update:  { label: 'Perlu Update',  color: '#f59e0b', bg: 'rgba(245,158,11,0.12)' },
      kadaluarsa:    { label: 'Kadaluarsa',    color: '#ef4444', bg: 'rgba(239,68,68,0.12)'  },
    };

    function skorBar(skor) {
      const color = skor >= 80 ? '#10b981' : skor >= 40 ? '#f59e0b' : '#ef4444';
      return `<div class="skor-bar-wrap">
        <div class="skor-bar"><div class="skor-bar-fill" style="width:${skor}%;background:${color}"></div></div>
        <span class="skor-pct" style="color:${color}">${skor}%</span>
      </div>`;
    }

    let allData = [];

    async function load(statusFilter = '') {
      const container = document.getElementById('verifikasi-list');
      if (!container) return;
      container.innerHTML = `<div class="fb-loading">${svgIcon(ICONS.clock,18,18)}<span>Memuat data verifikasi...</span></div>`;

      // Clear search input on load/change
      const searchBox = document.getElementById('verifikasi-search');
      if (searchBox) searchBox.value = '';

      const url = `api/verifikasi.php?action=list${statusFilter ? '&status=' + statusFilter : ''}`;
      try {
        const res  = await fetch(url);
        const json = await res.json();
        if (!json.success) throw new Error(json.message);

        // Update summary count
        const s = json.summary || {};
        document.getElementById('verif-count-ok')?.setAttribute('data-val',  s.terverifikasi || 0);
        document.getElementById('verif-count-warn')?.setAttribute('data-val', s.perlu_update  || 0);
        document.getElementById('verif-count-err')?.setAttribute('data-val',  s.kadaluarsa   || 0);
        ['ok','warn','err'].forEach(k => {
          const el = document.getElementById(`verif-count-${k}`);
          if (el) el.textContent = el.getAttribute('data-val');
        });

        allData = json.data || [];
        renderList();
      } catch (e) {
        container.innerHTML = `<div class="fb-error">${svgIcon(ICONS.alert,16,16)} ${e.message}</div>`;
      }
    }

    function renderList() {
      const container = document.getElementById('verifikasi-list');
      if (!container) return;

      const searchVal = document.getElementById('verifikasi-search')?.value.toLowerCase() || '';
      const filtered = allData.filter(w => {
        return !searchVal || 
               w.nama_kepala_keluarga.toLowerCase().includes(searchVal) ||
               w.no_kk.includes(searchVal) ||
               (w.kelurahan || '').toLowerCase().includes(searchVal);
      });

      if (!filtered.length) {
        container.innerHTML = `<div class="fb-empty">${svgIcon(ICONS.check2,20,20)}<div>Tidak ada data warga ditemukan</div></div>`;
        return;
      }

      container.innerHTML = filtered.map(w => {
        const stsCfg = STATUS_CFG[w.status_verifikasi] || STATUS_CFG.terverifikasi;
        const det    = w.detail_skor || {};
        return `<div class="verif-item">
          <div class="verif-item-header">
            <div>
              <div class="verif-item-nama">${w.nama_kepala_keluarga}</div>
              <div class="verif-item-sub">${w.kelurahan || ''} · No.KK: ${w.no_kk}</div>
            </div>
            <span class="fb-badge" style="background:${stsCfg.bg};color:${stsCfg.color}">${stsCfg.label}</span>
          </div>
          ${skorBar(w.skor_kepercayaan)}
          <div class="verif-meta">
            <span>${svgIcon(ICONS.clock,10,10)} Verif: ${w.tanggal_verifikasi ? new Date(w.tanggal_verifikasi).toLocaleDateString('id-ID') : 'Belum pernah'}</span>
            ${det.hari_sejak_verifikasi != null ? `<span>${det.hari_sejak_verifikasi} hari lalu</span>` : ''}
            ${det.tanggal_kadaluarsa ? `<span>Exp: ${new Date(det.tanggal_kadaluarsa).toLocaleDateString('id-ID')}</span>` : ''}
          </div>
          <button class="btn btn-primary btn-xs" style="margin-top:6px;width:100%"
            onclick="App.editWarga(${w.id})">
            ${svgIcon(ICONS.check2,11,11)} Catat Verifikasi &amp; Edit
          </button>
        </div>`;
      }).join('');
    }

    function openVerifModal(wargaId, namWarga) {
      document.getElementById('verif-modal-nama').textContent  = namWarga;
      document.getElementById('verif-modal-id').value          = wargaId;
      document.getElementById('verif-modal-tanggal').value     = new Date().toLocaleDateString('en-CA');
      document.getElementById('verif-modal-petugas').value     = '';
      document.getElementById('verif-modal-catatan').value     = '';
      showModal('modal-verifikasi');
    }

    async function simpanVerifikasi() {
      const wargaId = document.getElementById('verif-modal-id').value;
      const petugas = document.getElementById('verif-modal-petugas').value.trim();
      const tanggal = document.getElementById('verif-modal-tanggal').value;
      const catatan = document.getElementById('verif-modal-catatan').value;

      try {
        const res  = await fetch('api/verifikasi.php', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ warga_id: parseInt(wargaId), petugas, tanggal, catatan }),
        });
        const json = await res.json();
        if (json.success) {
          toast(json.message, 'success');
          closeModal('modal-verifikasi');
          load(document.getElementById('filter-verif-status')?.value || '');
        } else toast(json.message, 'error');
      } catch { toast('Gagal menyimpan verifikasi', 'error'); }
    }

    async function loadKonfig() {
      try {
        const res  = await fetch('api/verifikasi.php?action=config');
        const json = await res.json();
        if (!json.success) return;
        const container = document.getElementById('konfig-list');
        if (!container) return;
        konfig = {};
        json.data.forEach(k => { konfig[k.kunci] = k; });
        container.innerHTML = json.data.map(k => `
          <div class="konfig-item">
            <label class="konfig-label">${k.label || k.kunci}</label>
            ${k.deskripsi ? `<div class="konfig-desc">${k.deskripsi}</div>` : ''}
            <input type="${k.tipe === 'integer' || k.tipe === 'decimal' ? 'number' : 'text'}"
              class="form-control konfig-input"
              id="konfig-${k.kunci}"
              value="${k.nilai}"
              step="${k.tipe === 'decimal' ? '100000' : '1'}"
              data-kunci="${k.kunci}">
          </div>`).join('');
      } catch { /* silent */ }
    }

    async function simpanKonfig() {
      const inputs  = document.querySelectorAll('.konfig-input');
      const payload = {};
      inputs.forEach(el => { payload[el.dataset.kunci] = el.value; });
      try {
        const res  = await fetch('api/verifikasi.php', {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(payload),
        });
        const json = await res.json();
        toast(json.message, json.success ? 'success' : 'error');
        if (json.success) load();
      } catch { toast('Gagal menyimpan konfigurasi', 'error'); }
    }

    return { load, renderSearch: renderList, openVerifModal, simpanVerifikasi, loadKonfig, simpanKonfig, open: () => { showModal('modal-premium-verifikasi'); load(); loadKonfig(); } };
  })();

  /* ══════════════════════════════════════════════════
     ░░ FITUR 3: POTENSI KEMANDIRIAN ░░
  ══════════════════════════════════════════════════ */
  const Kemandirian = (() => {
    const STATUS_CFG = {
      sangat_bergantung:  { label: 'Sangat Bergantung', color: '#ef4444', bg: 'rgba(239,68,68,0.12)',   icon: '🔴' },
      bergantung:         { label: 'Bergantung',         color: '#f87171', bg: 'rgba(248,113,113,0.12)', icon: '🟠' },
      berkembang:         { label: 'Berkembang',         color: '#f59e0b', bg: 'rgba(245,158,11,0.12)',  icon: '🟡' },
      berpotensi_mandiri: { label: 'Berpotensi Mandiri', color: '#6366f1', bg: 'rgba(99,102,241,0.12)', icon: '🔵' },
      mandiri:            { label: 'Mandiri / Siap Exit',color: '#10b981', bg: 'rgba(16,185,129,0.12)', icon: '🟢' },
    };

    function skorGauge(skor, label) {
      const deg   = Math.round(skor / 100 * 180);
      const color = skor >= 80 ? '#10b981' : skor >= 61 ? '#6366f1' : skor >= 41 ? '#f59e0b' : skor >= 21 ? '#f87171' : '#ef4444';
      return `<div class="kemandirian-gauge" title="${label}: ${skor}/100">
        <svg viewBox="0 0 80 44" width="80" height="44">
          <path d="M8,40 A32,32 0 0,1 72,40" fill="none" stroke="var(--border)" stroke-width="7" stroke-linecap="round"/>
          <path d="M8,40 A32,32 0 0,1 72,40" fill="none" stroke="${color}" stroke-width="7" stroke-linecap="round"
            stroke-dasharray="${deg * 0.558} 200" />
        </svg>
        <div class="gauge-val" style="color:${color}">${skor}</div>
        <div class="gauge-label">${label}</div>
      </div>`;
    }

    let allData = [];

    async function load(statusFilter = '') {
      const container = document.getElementById('kemandirian-list');
      if (!container) return;
      container.innerHTML = `<div class="fb-loading">${svgIcon(ICONS.trend,18,18)}<span>Menghitung skor kemandirian...</span></div>`;

      // Clear search input on load/change
      const searchBox = document.getElementById('kemandirian-search');
      if (searchBox) searchBox.value = '';

      const url = `api/kemandirian.php?action=list${statusFilter ? '&status=' + statusFilter : ''}`;
      try {
        const res  = await fetch(url);
        const json = await res.json();
        if (!json.success) throw new Error(json.message);

        // Update stat cards
        const summaryMap = {};
        json.summary.forEach(s => { summaryMap[s.status] = s; });
        document.getElementById('kemandirian-siap-exit').textContent = json.siap_exit || 0;

        allData = json.data || [];
        renderList();
        return;

        container.innerHTML = json.data.map(w => {
          const stsCfg  = STATUS_CFG[w.status_kemandirian] || STATUS_CFG.bergantung;
          const det     = w.detail_skor || {};
          const estBulan = det.estimasi_bulan_mandiri;

          return `<div class="kemandirian-item" style="border-left:3px solid ${stsCfg.color}">
            <div class="kemandirian-item-header">
              <div>
                <div class="kemandirian-nama">${w.nama_kepala_keluarga}</div>
                <div class="kemandirian-sub">${formatRp(w.penghasilan_bulanan)}/bln · ${w.jumlah_tanggungan} tanggungan</div>
              </div>
              <span class="fb-badge" style="background:${stsCfg.bg};color:${stsCfg.color}">${stsCfg.icon} ${stsCfg.label}</span>
            </div>

            <div class="kemandirian-gauges">
              ${skorGauge(w.skor_kemandirian, 'Total')}
              ${det.skor_penghasilan != null ? skorGauge(det.skor_penghasilan, 'Penghasilan') : ''}
              ${det.skor_status_kerja != null ? skorGauge(det.skor_status_kerja, 'Kerja') : ''}
              ${det.skor_tanggungan != null ? skorGauge(det.skor_tanggungan, 'Tanggungan') : ''}
            </div>

            ${estBulan > 0 ? `<div class="kemandirian-est">
              ${svgIcon(ICONS.clock,11,11)} Est. mandiri: <b>~${estBulan} bulan</b>
            </div>` : w.status_kemandirian === 'mandiri' ? `<div class="kemandirian-est" style="color:var(--success)">
              ${svgIcon(ICONS.check2,11,11)} Siap keluar dari daftar bantuan
            </div>` : ''}

            ${det.rekomendasi?.length ? `<div class="kemandirian-rek">
              ${det.rekomendasi.map(r => `<div class="kemandirian-rek-item">${svgIcon(ICONS.trend,10,10)} ${r}</div>`).join('')}
            </div>` : ''}

            ${w.tanggal_exit_plan ? `<div style="font-size:10px;margin-top:4px;color:var(--text-muted)">
              ${svgIcon(ICONS.exit,10,10)} Target exit: <b>${new Date(w.tanggal_exit_plan).toLocaleDateString('id-ID')}</b>
            </div>` : ''}

            <button class="btn btn-ghost btn-xs" style="margin-top:6px;width:100%"
              onclick="FiturBaru.Kemandirian.openCatatanModal(${w.id}, '${w.nama_kepala_keluarga.replace(/'/g, "\\'")}', '${w.tanggal_exit_plan || ''}', '${w.catatan_kemandirian?.replace(/'/g, "\\'") || ''}')">
              ${svgIcon(ICONS.gear,11,11)} Catat Perkembangan
            </button>
          </div>`;
        }).join('');
      } catch (e) {
        container.innerHTML = `<div class="fb-error">${svgIcon(ICONS.alert,16,16)} ${e.message}</div>`;
      }
    }

    function renderList() {
      const container = document.getElementById('kemandirian-list');
      if (!container) return;

      const searchVal = document.getElementById('kemandirian-search')?.value.toLowerCase() || '';
      const filtered = allData.filter(w => {
        return !searchVal || 
               w.nama_kepala_keluarga.toLowerCase().includes(searchVal) ||
               (w.pekerjaan || '').toLowerCase().includes(searchVal);
      });

      if (!filtered.length) {
        container.innerHTML = `<div class="fb-empty">${svgIcon(ICONS.chart,20,20)}<div>Tidak ada data warga ditemukan</div></div>`;
        return;
      }

      container.innerHTML = filtered.map(w => {
        const stsCfg  = STATUS_CFG[w.status_kemandirian] || STATUS_CFG.bergantung;
        const det     = w.detail_skor || {};
        const estBulan = det.estimasi_bulan_mandiri;

        return `<div class="kemandirian-item" style="border-left:3px solid ${stsCfg.color}">
          <div class="kemandirian-item-header">
            <div>
              <div class="kemandirian-nama">${w.nama_kepala_keluarga}</div>
              <div class="kemandirian-sub">${formatRp(w.penghasilan_bulanan)}/bln · ${w.jumlah_tanggungan} tanggungan</div>
            </div>
            <span class="fb-badge" style="background:${stsCfg.bg};color:${stsCfg.color}">${stsCfg.icon} ${stsCfg.label}</span>
          </div>

          <div class="kemandirian-gauges">
            ${skorGauge(w.skor_kemandirian, 'Total')}
            ${det.skor_penghasilan != null ? skorGauge(det.skor_penghasilan, 'Penghasilan') : ''}
            ${det.skor_status_kerja != null ? skorGauge(det.skor_status_kerja, 'Kerja') : ''}
            ${det.skor_tanggungan != null ? skorGauge(det.skor_tanggungan, 'Tanggungan') : ''}
          </div>

          ${estBulan > 0 ? `<div class="kemandirian-est">
            ${svgIcon(ICONS.clock,11,11)} Est. mandiri: <b>~${estBulan} bulan</b>
          </div>` : w.status_kemandirian === 'mandiri' ? `<div class="kemandirian-est" style="color:var(--success)">
            ${svgIcon(ICONS.check2,11,11)} Siap keluar dari daftar bantuan
          </div>` : ''}

          ${det.rekomendasi?.length ? `<div class="kemandirian-rek">
            ${det.rekomendasi.map(r => `<div class="kemandirian-rek-item">${svgIcon(ICONS.trend,10,10)} ${r}</div>`).join('')}
          </div>` : ''}

          ${w.tanggal_exit_plan ? `<div style="font-size:10px;margin-top:4px;color:var(--text-muted)">
            ${svgIcon(ICONS.exit,10,10)} Target exit: <b>${new Date(w.tanggal_exit_plan).toLocaleDateString('id-ID')}</b>
          </div>` : ''}

          <button class="btn btn-ghost btn-xs" style="margin-top:6px;width:100%"
            onclick="FiturBaru.Kemandirian.openCatatanModal(${w.id}, '${w.nama_kepala_keluarga.replace(/'/g, "\\'")}', '${w.tanggal_exit_plan || ''}', '${w.catatan_kemandirian?.replace(/'/g, "\\'") || ''}')">
            ${svgIcon(ICONS.gear,11,11)} Catat Perkembangan
          </button>
        </div>`;
      }).join('');
    }

    function openCatatanModal(wargaId, nama, exitPlan, catatan) {
      document.getElementById('kemandirian-modal-nama').textContent   = nama;
      document.getElementById('kemandirian-modal-id').value           = wargaId;
      document.getElementById('kemandirian-modal-exit').value         = exitPlan;
      document.getElementById('kemandirian-modal-catatan').value      = catatan;
      showModal('modal-kemandirian');
    }

    async function simpanCatatan() {
      const wargaId   = document.getElementById('kemandirian-modal-id').value;
      const catatan   = document.getElementById('kemandirian-modal-catatan').value;
      const exitPlan  = document.getElementById('kemandirian-modal-exit').value;

      try {
        const res  = await fetch('api/kemandirian.php', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            warga_id:         parseInt(wargaId),
            catatan,
            tanggal_exit_plan: exitPlan || null,
          }),
        });
        const json = await res.json();
        if (json.success) {
          toast(json.message, 'success');
          closeModal('modal-kemandirian');
          load(document.getElementById('filter-kemandirian-status')?.value || '');
        } else toast(json.message, 'error');
      } catch { toast('Gagal menyimpan', 'error'); }
    }

    return { load, renderSearch: renderList, openCatatanModal, simpanCatatan, open: () => { showModal('modal-premium-kemandirian'); load(); } };
  })();

  /* ══════════════════════════════════════════════════
     ░░ FITUR 4: KEBUTUHAN & KONTRIBUSI ░░
  ══════════════════════════════════════════════════ */
  const Kebutuhan = (() => {
    let kebutuhanData = [];
    let activeSubTab = 'daftar'; // 'daftar', 'riwayat', or 'konfirmasi'

    async function load() {
      const container = document.getElementById('kebutuhan-panel-content');
      if (!container) return;

      const user = App.getCurrentUser();
      const role = user ? user.role : 'guest';

      // Enforce default tab based on role transitions
      if (activeSubTab === 'riwayat' && role !== 'kontributor') {
        activeSubTab = 'daftar';
      }
      if (activeSubTab === 'konfirmasi' && !['admin', 'koordinator'].includes(role)) {
        activeSubTab = 'daftar';
      }
      if (role === 'guest') {
        activeSubTab = 'daftar';
      }

      let subTabsHtml = '';
      if (role === 'kontributor') {
        subTabsHtml = `
          <div class="fb-sub-tabs" style="margin-bottom: 12px;">
            <button class="fb-sub-tab ${activeSubTab === 'daftar' ? 'active' : ''}" onclick="FiturBaru.Kebutuhan.switchTab('daftar')">Kebutuhan Sosial</button>
            <button class="fb-sub-tab ${activeSubTab === 'riwayat' ? 'active' : ''}" onclick="FiturBaru.Kebutuhan.switchTab('riwayat')">Riwayat Donasi Saya</button>
          </div>
        `;
      } else if (role === 'koordinator' || role === 'admin') {
        subTabsHtml = `
          <div class="fb-sub-tabs" style="margin-bottom: 12px;">
            <button class="fb-sub-tab ${activeSubTab === 'daftar' ? 'active' : ''}" onclick="FiturBaru.Kebutuhan.switchTab('daftar')">Kelola Kebutuhan</button>
            <button class="fb-sub-tab ${activeSubTab === 'konfirmasi' ? 'active' : ''}" onclick="FiturBaru.Kebutuhan.switchTab('konfirmasi')">Verifikasi Donasi</button>
          </div>
        `;
      } else if (role === 'guest') {
        subTabsHtml = '';
      }

      container.innerHTML = `
        ${subTabsHtml}
        <div id="kebutuhan-sub-panel-content">
          <div class="fb-loading"><span>Memuat data...</span></div>
        </div>
      `;

      if (activeSubTab === 'daftar') {
        await loadKebutuhanList();
      } else if (activeSubTab === 'riwayat') {
        await loadRiwayatDonasi();
      } else if (activeSubTab === 'konfirmasi') {
        await loadVerifikasiDonasi();
      }
    }

    // Force refresh Kebutuhan tab if it's currently active
    function refreshIfActive() {
      const kebutuhanTab = document.getElementById('tab-btn-kebutuhan');
      if (kebutuhanTab && kebutuhanTab.classList.contains('active')) {
        load();
      }
    }

    async function loadKebutuhanList() {
      const subContainer = document.getElementById('kebutuhan-sub-panel-content');
      if (!subContainer) return;

      try {
        const res = await fetch('api/kebutuhan.php');
        const json = await res.json();
        if (!json.success) throw new Error(json.message);

        kebutuhanData = json.data || [];
        const user = App.getCurrentUser();
        const role = user ? user.role : 'guest';

        let addBtnHtml = '';
        if (role === 'admin' || role === 'koordinator') {
          addBtnHtml = `
            <button class="btn btn-primary btn-sm btn-block" style="margin-bottom: 12px; display:flex; align-items:center; justify-content:center; gap: 4px;" onclick="FiturBaru.Kebutuhan.openFormModal()">
              ${svgIcon(ICONS.refresh, 11, 11)} Tambah Kebutuhan Baru
            </button>
          `;
        }

        if (kebutuhanData.length === 0) {
          subContainer.innerHTML = `
            ${addBtnHtml}
            <div class="fb-empty">Belum ada kebutuhan bantuan terdaftar.</div>
          `;
          return;
        }

        const cardsHtml = kebutuhanData.map(k => {
          const gathered = parseFloat(k.jumlah_terkumpul || 0);
          const required = parseFloat(k.jumlah_dibutuhkan || 0);
          const progress = Math.min(100, Math.round((gathered / required) * 100)) || 0;
          const sisa = Math.max(0, required - gathered);
          const ibadahNama = k.nama_rumah_ibadah || k.nama_ibadah || 'Rumah Ibadah';

          let actionButtons = '';
          if (role === 'admin' || (role === 'koordinator' && user.rumah_ibadah_id == k.rumah_ibadah_id)) {
            actionButtons = `
              <div style="display:flex; gap:6px;">
                <button class="btn btn-primary btn-xs" style="padding: 3px 8px" onclick="FiturBaru.Kebutuhan.openFormModal(${k.id})">Edit</button>
                <button class="btn btn-danger btn-xs" style="padding: 3px 8px" onclick="FiturBaru.Kebutuhan.deleteKebutuhan(${k.id})">Hapus</button>
              </div>
            `;
          } else {
            if (sisa > 0) {
              actionButtons = `
                <button class="btn btn-success btn-xs" style="padding: 4px 10px; font-weight:700" onclick="FiturBaru.Kebutuhan.triggerDonation(${k.id}, ${sisa}, '${k.jenis_bantuan.replace(/'/g, "\\'")}', '${ibadahNama.replace(/'/g, "\\'")}')">
                  Beri Donasi
                </button>
              `;
            } else {
              actionButtons = `<span class="fb-badge badge-sudah-terima">${svgIcon(ICONS.check2, 10, 10)} Terpenuhi</span>`;
            }
          }

          const categoryIcons = {
            barang: '📦',
            uang: '💰',
            jasa: '🤝'
          };
          const catIcon = categoryIcons[k.kategori] || '📦';

          return `
            <div class="kebutuhan-card">
              <div class="kebutuhan-header">
                <div>
                  <div class="kebutuhan-ibadah-nama">${ibadahNama}</div>
                  <div class="kebutuhan-bantuan-jenis">${catIcon} ${k.jenis_bantuan} (${k.kategori})</div>
                </div>
              </div>
              
              <div class="kebutuhan-progress-section">
                <div class="kebutuhan-progress-text">
                  <span>Terkumpul: ${gathered} / ${required} ${k.satuan ? (k.satuan === 'nominal' ? '(Rp)' : k.satuan) : ''}</span>
                  <span>${progress}%</span>
                </div>
                <div class="kebutuhan-progress-bar">
                  <div class="kebutuhan-progress-fill" style="width: ${progress}%"></div>
                </div>
              </div>

              <div class="kebutuhan-footer">
                <div class="kebutuhan-sisa ${sisa === 0 ? 'kebutuhan-penuh' : ''}">
                  ${sisa > 0 ? `Sisa Kebutuhan: <b>${sisa}</b>` : 'Kebutuhan Terpenuhi'}
                </div>
                ${actionButtons}
              </div>
            </div>
          `;
        }).join('');

        subContainer.innerHTML = addBtnHtml + cardsHtml;
      } catch (e) {
        subContainer.innerHTML = `<div class="fb-error">${e.message}</div>`;
      }
    }

    async function loadRiwayatDonasi() {
      const subContainer = document.getElementById('kebutuhan-sub-panel-content');
      if (!subContainer) return;

      try {
        const res = await fetch('api/kontribusi.php');
        const json = await res.json();
        if (!json.success) throw new Error(json.message);

        const list = json.data || [];
        if (list.length === 0) {
          subContainer.innerHTML = `<div class="fb-empty">Anda belum pernah mengirimkan donasi.</div>`;
          return;
        }

        subContainer.innerHTML = list.map(c => {
          const statusCls = c.status === 'confirmed' ? 'badge-sudah-terima' : c.status === 'rejected' ? 'badge-sangat-miskin' : 'badge-belum-terima';
          const statusLabel = c.status === 'confirmed' ? 'Disetujui' : c.status === 'rejected' ? 'Ditolak' : 'Menunggu Konfirmasi';

          return `
            <div class="kontribusi-item">
              <div class="kontribusi-header">
                <span style="font-size: 11px; font-weight: 700; color: var(--text-primary);">${c.nama_ibadah}</span>
                <span class="fb-badge ${statusCls}">${statusLabel}</span>
              </div>
              <div style="font-size: 10px; color: var(--text-muted); margin-bottom: 4px;">
                Bantuan: <b>${c.jenis_bantuan}</b>
              </div>
              <div style="font-size: 11px; color: var(--text-secondary); display: flex; justify-content: space-between;">
                <span>Jumlah: <b>${c.jumlah}</b> (${c.tipe_kontribusi})</span>
                <span>${new Date(c.created_at).toLocaleDateString('id-ID')}</span>
              </div>
              ${c.catatan ? `<div style="font-size: 9.5px; color: var(--text-muted); margin-top: 4px; border-left: 2px solid var(--border); padding-left: 6px;">Catatan: ${c.catatan}</div>` : ''}
            </div>
          `;
        }).join('');
      } catch (e) {
        subContainer.innerHTML = `<div class="fb-error">${e.message}</div>`;
      }
    }

    async function loadVerifikasiDonasi() {
      const subContainer = document.getElementById('kebutuhan-sub-panel-content');
      if (!subContainer) return;

      try {
        const res = await fetch('api/kontribusi.php');
        const json = await res.json();
        if (!json.success) throw new Error(json.message);

        const list = json.data || [];
        if (list.length === 0) {
          subContainer.innerHTML = `<div class="fb-empty">Tidak ada donasi masuk untuk rumah ibadah Anda.</div>`;
          return;
        }

        subContainer.innerHTML = list.map(c => {
          const isPending = c.status === 'pending';
          const statusCls = c.status === 'confirmed' ? 'badge-sudah-terima' : c.status === 'rejected' ? 'badge-sangat-miskin' : 'badge-belum-terima';
          const statusLabel = c.status === 'confirmed' ? 'Disetujui' : c.status === 'rejected' ? 'Ditolak' : 'Menunggu Konfirmasi';

          return `
            <div class="kontribusi-item">
              <div class="kontribusi-header">
                <span style="font-size: 11px; font-weight: 700; color: var(--text-primary);">${c.nama_kontributor}</span>
                <span class="fb-badge ${statusCls}">${statusLabel}</span>
              </div>
              <div style="font-size: 10px; color: var(--text-muted); margin-bottom: 4px;">
                Ibadah: <b>${c.nama_ibadah}</b> · Bantuan: <b>${c.jenis_bantuan}</b>
              </div>
              <div style="font-size: 11px; color: var(--text-secondary); display: flex; justify-content: space-between; align-items: center;">
                <span>Jumlah: <b>${c.jumlah}</b> (${c.tipe_kontribusi})</span>
                <span>Contact: ${c.kontak_kontributor || '–'}</span>
              </div>
              ${c.catatan ? `<div style="font-size: 10px; color: var(--text-muted); margin-top: 4px; font-style: italic;">"${c.catatan}"</div>` : ''}
              ${isPending ? `
                <div style="margin-top: 8px; display: flex; gap: 6px;">
                  <button class="btn btn-success btn-xs" style="padding: 4px 10px" onclick="FiturBaru.Kebutuhan.verifyDonasi(${c.id}, 'confirmed')">Setujui</button>
                  <button class="btn btn-danger btn-xs" style="padding: 4px 10px" onclick="FiturBaru.Kebutuhan.verifyDonasi(${c.id}, 'rejected')">Tolak</button>
                </div>
              ` : ''}
            </div>
          `;
        }).join('');
      } catch (e) {
        subContainer.innerHTML = `<div class="fb-error">${e.message}</div>`;
      }
    }

    function switchTab(tab) {
      activeSubTab = tab;
      load();
    }

    function openFormModal(id = null) {
      const modal = document.getElementById('modal-kebutuhan-form');
      if (!modal) return;

      // Prevent non-authorized users from opening the form (defense-in-depth)
      const currentUser = App.getCurrentUser();
      const role = currentUser ? currentUser.role : 'guest';
      if (!['admin', 'koordinator'].includes(role)) {
        toast('Hanya Admin atau Koordinator yang dapat menambah / mengedit kebutuhan.', 'error');
        return;
      }

      const titleEl = document.getElementById('modal-kebutuhan-title');
      const idInput = document.getElementById('kebutuhan-id');
      const ibadahSelect = document.getElementById('kebutuhan-ibadah-id');
      const katSelect = document.getElementById('kebutuhan-kategori');
      const jenisInput = document.getElementById('kebutuhan-jenis-bantuan');
      const jumlahInput = document.getElementById('kebutuhan-jumlah-dibutuhkan');
      const ibadahContainer = document.getElementById('kebutuhan-ibadah-select-container');

      if (ibadahSelect) {
        const list = App.getIbadahData() || [];
        ibadahSelect.innerHTML = list.map(i => `<option value="${i.id}">${i.nama}</option>`).join('');
      }

      const user = App.getCurrentUser();
      if (user && user.role === 'koordinator') {
        if (ibadahContainer) ibadahContainer.style.display = 'none';
        if (ibadahSelect) ibadahSelect.value = user.rumah_ibadah_id;
      } else {
        if (ibadahContainer) ibadahContainer.style.display = 'block';
      }

      if (id) {
        titleEl.textContent = 'Edit Kebutuhan Bantuan';
        const d = kebutuhanData.find(x => x.id == id);
        if (d) {
          idInput.value = d.id;
          if (ibadahSelect) ibadahSelect.value = d.rumah_ibadah_id;
          katSelect.value = d.kategori;
          jenisInput.value = d.jenis_bantuan;
          jumlahInput.value = d.jumlah_dibutuhkan;
          const satuanSelect = document.getElementById('kebutuhan-satuan');
          if (satuanSelect) satuanSelect.value = d.satuan || (d.kategori === 'uang' ? 'nominal' : (d.kategori === 'jasa' ? 'orang' : 'unit'));
        }
      } else {
        titleEl.textContent = 'Tambah Kebutuhan Bantuan';
        idInput.value = '';
        jenisInput.value = '';
        jumlahInput.value = '';
        const satuanSelect = document.getElementById('kebutuhan-satuan');
        if (satuanSelect) {
          // default based on kategori
          const defKat = katSelect ? katSelect.value : 'barang';
          satuanSelect.value = defKat === 'uang' ? 'nominal' : (defKat === 'jasa' ? 'orang' : 'unit');
        }
      }

      // Ensure kategori change updates jumlah label/hint
      const katSelectEl = document.getElementById('kebutuhan-kategori');
      const jumlahGroup = document.getElementById('kebutuhan-jumlah-group');
      const jumlahLabel = document.getElementById('kebutuhan-jumlah-label');
      const jumlahHint = document.getElementById('kebutuhan-jumlah-hint');

      const satuanSelectEl = document.getElementById('kebutuhan-satuan');

      function updateJumlahVisibility() {
        const val = katSelectEl ? katSelectEl.value : 'barang';
        if (val === 'uang') {
          // For monetary needs, show amount and hint
          if (jumlahGroup) jumlahGroup.style.display = '';
          if (jumlahLabel) jumlahLabel.textContent = 'Jumlah Dibutuhkan (nominal dalam satuan lokal) *';
          if (jumlahHint) jumlahHint.textContent = 'Masukkan jumlah dana yang dibutuhkan (angka, tanpa pemisah).';
          if (satuanSelectEl) satuanSelectEl.value = 'nominal';
        } else if (val === 'jasa') {
          // For jasa, show count of tenaga/relawan needed
          if (jumlahGroup) jumlahGroup.style.display = '';
          if (jumlahLabel) jumlahLabel.textContent = 'Jumlah Tenaga / Relawan Dibutuhkan *';
          if (jumlahHint) jumlahHint.textContent = 'Masukkan jumlah tenaga/relawan yang diperlukan.';
          if (satuanSelectEl) satuanSelectEl.value = 'orang';
        } else {
          // barang
          if (jumlahGroup) jumlahGroup.style.display = '';
          if (jumlahLabel) jumlahLabel.textContent = 'Jumlah Dibutuhkan *';
          if (jumlahHint) jumlahHint.textContent = 'Untuk barang: jumlah unit yang dibutuhkan.';
          if (satuanSelectEl) satuanSelectEl.value = 'unit';
        }
      }

      if (katSelectEl) {
        katSelectEl.removeEventListener('change', updateJumlahVisibility);
        katSelectEl.addEventListener('change', updateJumlahVisibility);
      }
      updateJumlahVisibility();

      modal.classList.add('show');
    }

    async function saveKebutuhan() {
      const id = document.getElementById('kebutuhan-id').value;
      const ibadahId = document.getElementById('kebutuhan-ibadah-id').value;
      const kategori = document.getElementById('kebutuhan-kategori').value;
      const jenis = document.getElementById('kebutuhan-jenis-bantuan').value.trim();
      const jumlah = document.getElementById('kebutuhan-jumlah-dibutuhkan').value;
      const satuan = document.getElementById('kebutuhan-satuan') ? document.getElementById('kebutuhan-satuan').value : 'unit';

      if (!jenis || jumlah === '' || jumlah === null) {
        toast('Semua input wajib diisi!', 'error');
        return;
      }

      // Normalize kategori to allowed DB values
      const allowed = ['barang', 'uang', 'jasa'];
      const kategoriNorm = allowed.includes(kategori) ? kategori : 'barang';

      const method = id ? 'PUT' : 'POST';
      const body = { rumah_ibadah_id: parseInt(ibadahId), kategori: kategoriNorm, jenis_bantuan: jenis, jumlah_dibutuhkan: parseFloat(jumlah), satuan };
      if (id) body.id = parseInt(id);

      try {
        const res = await fetch('api/kebutuhan.php', {
          method,
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(body)
        });
        const json = await res.json();
        if (json.success) {
          toast(json.message, 'success');
          closeModal('modal-kebutuhan-form');
          load();
        } else {
          toast(json.message, 'error');
        }
      } catch (e) {
        toast('Gagal menyimpan kebutuhan', 'error');
      }
    }

    async function deleteKebutuhan(id) {
      if (!confirm('Apakah Anda yakin ingin menghapus kebutuhan ini?')) return;

      try {
        const res = await fetch(`api/kebutuhan.php?id=${id}`, { method: 'DELETE' });
        const json = await res.json();
        if (json.success) {
          toast(json.message, 'success');
          load();
        } else {
          toast(json.message, 'error');
        }
      } catch (e) {
        toast('Gagal menghapus kebutuhan', 'error');
      }
    }

    function triggerDonation(kebutuhanId, sisa, jenis, ibadahNama) {
      App.checkAuth({ type: 'donate', kebutuhan_id: kebutuhanId, sisa, jenis, ibadah_nama: ibadahNama }, () => {
        openDonationModal(kebutuhanId, sisa, jenis, ibadahNama);
      });
    }

    function openDonationModal(kebutuhanId, sisa, jenis, ibadahNama) {
      const modal = document.getElementById('modal-kontribusi-form');
      if (!modal) return;

      document.getElementById('kontribusi-kebutuhan-id').value = kebutuhanId;
      document.getElementById('kontribusi-target-ibadah').textContent = ibadahNama;
      document.getElementById('kontribusi-target-detail').textContent = `Bantuan: ${jenis} (Sisa: ${sisa})`;
      
      const countInput = document.getElementById('kontribusi-jumlah');
      countInput.value = '';
      countInput.max = sisa;
      
      const maxHint = document.getElementById('kontribusi-max-hint');
      if (maxHint) maxHint.textContent = `Batas Maksimal: ${sisa}`;

      const nameInput = document.getElementById('kontribusi-nama');
      const contactInput = document.getElementById('kontribusi-kontak');
      const typeSelect = document.getElementById('kontribusi-tipe');

      const user = App.getCurrentUser();
      if (user) {
        nameInput.value = user.username || '';
        nameInput.readOnly = true;
        contactInput.value = user.no_telp || '';
        contactInput.readOnly = true;
      } else {
        nameInput.value = '';
        nameInput.readOnly = false;
        contactInput.value = '';
        contactInput.readOnly = false;
      }

      // Auto-map contribution type based on need category
      const d = kebutuhanData.find(x => x.id == kebutuhanId);
      let mappedType = 'barang'; // default
      if (d) {
        if (d.kategori === 'uang') {
          mappedType = 'uang';
        } else if (['jasa', 'tenaga', 'relawan'].includes(d.kategori) || d.jenis_bantuan.toLowerCase().includes('relawan') || d.jenis_bantuan.toLowerCase().includes('tenaga') || d.jenis_bantuan.toLowerCase().includes('jasa')) {
          mappedType = 'tenaga';
        }
      }
      if (typeSelect) {
        typeSelect.value = mappedType;
        typeSelect.disabled = true; // Lock it to prevent manual modification
      }

      document.getElementById('kontribusi-catatan').value = '';

      modal.classList.add('show');
    }

    async function saveDonation() {
      const kebutuhanId = document.getElementById('kontribusi-kebutuhan-id').value;
      const nama = document.getElementById('kontribusi-nama').value.trim();
      const kontak = document.getElementById('kontribusi-kontak').value.trim();
      const tipe = document.getElementById('kontribusi-tipe').value;
      const jumlah = parseFloat(document.getElementById('kontribusi-jumlah').value);
      const catatan = document.getElementById('kontribusi-catatan').value.trim();

      if (!nama || !kontak || isNaN(jumlah) || jumlah <= 0) {
        toast('Nama, Kontak, dan Jumlah Donasi wajib diisi!', 'error');
        return;
      }

      const maxLimit = parseFloat(document.getElementById('kontribusi-jumlah').max);
      if (jumlah > maxLimit) {
        toast(`Jumlah kontribusi tidak boleh melebihi sisa kebutuhan (${maxLimit})!`, 'error');
        return;
      }

      try {
        const res = await fetch('api/kontribusi.php', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            kebutuhan_id: parseInt(kebutuhanId),
            nama_kontributor: nama,
            kontak_kontributor: kontak,
            tipe_kontribusi: tipe,
            jumlah,
            catatan
          })
        });
        const json = await res.json();
        if (json.success) {
          toast(json.message, 'success');
          closeModal('modal-kontribusi-form');
          load();
        } else {
          toast(json.message, 'error');
        }
      } catch (e) {
        toast('Gagal mengirimkan donasi', 'error');
      }
    }

    async function verifyDonasi(id, status) {
      if (!confirm(`Apakah Anda yakin ingin ${status === 'confirmed' ? 'menyetujui' : 'menolak'} donasi ini?`)) return;

      try {
        const res = await fetch('api/kontribusi.php', {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ id: parseInt(id), status })
        });
        const json = await res.json();
        if (json.success) {
          toast(json.message, 'success');
          load();
        } else {
          toast(json.message, 'error');
        }
      } catch (e) {
        toast('Gagal memverifikasi donasi', 'error');
      }
    }

    return {
      load,
      switchTab,
      openFormModal,
      saveKebutuhan,
      deleteKebutuhan,
      triggerDonation,
      openDonationModal,
      saveDonation,
      verifyDonasi,
      refreshIfActive
    };
  })();

  /* ══════════════════════════════════════════════════
     INISIALISASI TAB & EVENT LISTENER
  ══════════════════════════════════════════════════ */
  function init() {
    // Tambah tab baru ke sidebar jika belum ada
    injectSidebarTabs();
    injectModals();
    bindEvents();
    Kebutuhan.load();
  }

  function injectSidebarTabs() {
    // 1. Inject the three feature modals directly to body
    document.body.insertAdjacentHTML('beforeend', buildRedistribusiPanel());
    document.body.insertAdjacentHTML('beforeend', buildVerifikasiPanel());
    document.body.insertAdjacentHTML('beforeend', buildKemandirianPanel());

    // 2. Inject the advanced features section inside Overview tab
    const overviewTab = document.getElementById('tab-overview');
    if (overviewTab) {
      const fiturHtml = `
        <!-- Fitur Lanjutan -->
        <div class="section-title" style="margin-top: 15px;">
          ${svgIcon(ICONS.gear, 12, 12)}
          Fitur Lanjutan
        </div>
        <div class="ekon-grid" style="margin-bottom: 14px; display: flex; flex-direction: column; gap: 8px;">
          <div class="ekon-card" 
            onmouseover="this.style.borderColor='var(--accent-light)'" 
            onmouseout="this.style.borderColor='var(--border)'"
            style="cursor: pointer; padding: 12px; transition: all 0.2s; border-left: 3px solid var(--accent-light); flex: 1; border: 1px solid var(--border); border-radius: 8px; display: flex; align-items: center;"
            onclick="FiturBaru.Redistribusi.open()">
            <div style="flex: 1; min-width: 0;">
              <div style="font-size: 11px; font-weight: 700; color: var(--text-primary); display: flex; align-items: center; gap: 6px;">
                ${svgIcon(ICONS.swap, 12, 12)}
                Redistribusi Bantuan
              </div>
              <div style="font-size: 10px; color: var(--text-muted); margin-top: 3px; line-height: 1.4; white-space: normal;">
                Analisis beban distribusi & rekomendasi transfer bantuan antar rumah ibadah.
              </div>
            </div>
          </div>

          <div class="ekon-card" 
            onmouseover="this.style.borderColor='var(--success)'" 
            onmouseout="this.style.borderColor='var(--border)'"
            style="cursor: pointer; padding: 12px; transition: all 0.2s; border-left: 3px solid var(--success); flex: 1; border: 1px solid var(--border); border-radius: 8px; display: flex; align-items: center;"
            onclick="FiturBaru.Verifikasi.open()">
            <div style="flex: 1; min-width: 0;">
              <div style="font-size: 11px; font-weight: 700; color: var(--text-primary); display: flex; align-items: center; gap: 6px;">
                ${svgIcon(ICONS.shield, 12, 12)}
                Keterbaruan &amp; Verifikasi Data
              </div>
              <div style="font-size: 10px; color: var(--text-muted); margin-top: 3px; line-height: 1.4; white-space: normal;">
                Pantau waktu verifikasi, skor kepercayaan data, dan rekam kunjungan lapangan.
              </div>
            </div>
          </div>

          <div class="ekon-card" 
            onmouseover="this.style.borderColor='var(--warning)'" 
            onmouseout="this.style.borderColor='var(--border)'"
            style="cursor: pointer; padding: 12px; transition: all 0.2s; border-left: 3px solid var(--warning); flex: 1; border: 1px solid var(--border); border-radius: 8px; display: flex; align-items: center;"
            onclick="FiturBaru.Kemandirian.open()">
            <div style="flex: 1; min-width: 0;">
              <div style="font-size: 11px; font-weight: 700; color: var(--text-primary); display: flex; align-items: center; gap: 6px;">
                ${svgIcon(ICONS.trend, 12, 12)}
                Potensi Kemandirian Warga
              </div>
              <div style="font-size: 10px; color: var(--text-muted); margin-top: 3px; line-height: 1.4; white-space: normal;">
                Skor kemandirian warga, grafik gauge interaktif, dan penentuan exit plan.
              </div>
            </div>
          </div>
        </div>
      `;
      const legendaTitle = document.getElementById('section-legenda');
      if (legendaTitle) {
        legendaTitle.insertAdjacentHTML('beforebegin', fiturHtml);
      } else {
        overviewTab.insertAdjacentHTML('beforeend', fiturHtml);
      }
    }
  }

  /* ─── Premium Overlay Modals HTML Builders ─── */
  function buildRedistribusiPanel() {
    return `<div class="modal-overlay" id="modal-premium-redistribusi">
      <div class="modal" style="width: 520px; max-width: 95vw; max-height: 85vh; display: flex; flex-direction: column;">
        <div class="modal-header" style="position: sticky; top: 0; background: var(--bg-panel); z-index: 10; border-bottom: 1px solid var(--border);">
          <div class="modal-title" style="display: flex; align-items: center; gap: 8px;">
            ${svgIcon(ICONS.swap, 14, 14)}
            <span>Analisis &amp; Redistribusi Bantuan</span>
          </div>
          <button class="modal-close" onclick="document.getElementById('modal-premium-redistribusi').classList.remove('show')">
            <svg viewBox="0 0 24 24" width="13" height="13" stroke="currentColor" fill="none" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
          </button>
        </div>
        <div class="modal-body" style="padding: 16px; overflow-y: auto; flex: 1;">
          <div class="fb-sub-tabs">
            <button class="fb-sub-tab active" data-fbtab="analisis" onclick="switchFbTab(this,'redistribusi')">Analisis Beban</button>
            <button class="fb-sub-tab" data-fbtab="saran" onclick="switchFbTab(this,'redistribusi')">Saran Sistem</button>
            <button class="fb-sub-tab" data-fbtab="riwayat" onclick="switchFbTab(this,'redistribusi')">Riwayat</button>
          </div>

          <div class="fb-sub-panel active" id="redistribusi-analisis-wrap">
            <div id="redistribusi-summary-container"></div>
            <input type="text" id="redistribusi-search" class="form-control" placeholder="Cari rumah ibadah..." style="font-size:11px;padding:6px;margin-top:8px;margin-bottom:8px" oninput="FiturBaru.Redistribusi.renderSearch()">
            <div id="redistribusi-analisis">
              <div class="fb-empty">Memuat analisis beban...</div>
            </div>
          </div>
          <div class="fb-sub-panel" id="redistribusi-saran-wrap">
            <div id="redistribusi-saran"><div class="fb-empty">Memuat saran...</div></div>
          </div>
          <div class="fb-sub-panel" id="redistribusi-riwayat-wrap">
            <div id="redistribusi-riwayat"><div class="fb-empty">Memuat riwayat...</div></div>
          </div>
        </div>
      </div>
    </div>`;
  }

  function buildVerifikasiPanel() {
    return `<div class="modal-overlay" id="modal-premium-verifikasi">
      <div class="modal" style="width: 520px; max-width: 95vw; max-height: 85vh; display: flex; flex-direction: column;">
        <div class="modal-header" style="position: sticky; top: 0; background: var(--bg-panel); z-index: 10; border-bottom: 1px solid var(--border);">
          <div class="modal-title" style="display: flex; align-items: center; gap: 8px;">
            ${svgIcon(ICONS.shield, 14, 14)}
            <span>Keterbaruan &amp; Verifikasi Data</span>
          </div>
          <button class="modal-close" onclick="document.getElementById('modal-premium-verifikasi').classList.remove('show'); document.body.classList.remove('side-by-side-modals');">
            <svg viewBox="0 0 24 24" width="13" height="13" stroke="currentColor" fill="none" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
          </button>
        </div>
        <div class="modal-body" style="padding: 16px; overflow-y: auto; flex: 1;">
          <div class="verif-summary-row" style="margin-bottom: 12px; display: flex; gap: 8px;">
            <div class="verif-sum-card ok" style="flex: 1; text-align: center; padding: 6px; border-radius: 6px; background: rgba(16,185,129,0.08); border: 1px solid rgba(16,185,129,0.2);"><span id="verif-count-ok" style="font-weight: 700; color: var(--success);">–</span><small style="font-size: 9px; color: var(--text-muted);">Terverifikasi</small></div>
            <div class="verif-sum-card warn" style="flex: 1; text-align: center; padding: 6px; border-radius: 6px; background: rgba(245,158,11,0.08); border: 1px solid rgba(245,158,11,0.2);"><span id="verif-count-warn" style="font-weight: 700; color: var(--warning);">–</span><small style="font-size: 9px; color: var(--text-muted);">Perlu Update</small></div>
            <div class="verif-sum-card err" style="flex: 1; text-align: center; padding: 6px; border-radius: 6px; background: rgba(239,68,68,0.08); border: 1px solid rgba(239,68,68,0.2);"><span id="verif-count-err" style="font-weight: 700; color: var(--danger);">–</span><small style="font-size: 9px; color: var(--text-muted);">Kadaluarsa</small></div>
          </div>

          <div class="fb-sub-tabs">
            <button class="fb-sub-tab active" data-fbtab="list" onclick="switchFbTab(this,'verifikasi')">Daftar Warga</button>
            <button class="fb-sub-tab" data-fbtab="konfig" onclick="switchFbTab(this,'verifikasi')">Konfigurasi</button>
          </div>

          <div class="fb-sub-panel active" id="verifikasi-list-wrap">
            <div style="display:flex;gap:4px;margin-bottom:8px">
              <input type="text" id="verifikasi-search" class="form-control" placeholder="Cari nama, NIK, KK..." style="font-size:11px;padding:6px;flex:1" oninput="FiturBaru.Verifikasi.renderSearch()">
              <select id="filter-verif-status" class="form-control" style="font-size:11px;padding:5px;width:120px"
                onchange="FiturBaru.Verifikasi.load(this.value)">
                <option value="">Perlu Verifikasi</option>
                <option value="kadaluarsa">Kadaluarsa</option>
                <option value="perlu_update">Perlu Update</option>
                <option value="terverifikasi">Terverifikasi</option>
                <option value="semua">Semua Warga</option>
              </select>
            </div>
            <div id="verifikasi-list"><div class="fb-empty">Memuat data...</div></div>
          </div>

          <div class="fb-sub-panel" id="verifikasi-konfig-wrap">
            <div class="konfig-intro" style="font-size: 11px; color: var(--text-muted); margin-bottom: 10px;">Atur parameter keterbaruan data dan ambang batas kemandirian.</div>
            <div id="konfig-list"><div class="fb-loading">${svgIcon(ICONS.gear,16,16)}<span>Memuat konfigurasi...</span></div></div>
            <button class="btn btn-primary btn-block" style="margin-top:10px" onclick="FiturBaru.Verifikasi.simpanKonfig()">
              ${svgIcon(ICONS.check2,12,12)} Simpan Konfigurasi
            </button>
          </div>
        </div>
      </div>
    </div>`;
  }

  function buildKemandirianPanel() {
    return `<div class="modal-overlay" id="modal-premium-kemandirian">
      <div class="modal" style="width: 520px; max-width: 95vw; max-height: 85vh; display: flex; flex-direction: column;">
        <div class="modal-header" style="position: sticky; top: 0; background: var(--bg-panel); z-index: 10; border-bottom: 1px solid var(--border);">
          <div class="modal-title" style="display: flex; align-items: center; gap: 8px;">
            ${svgIcon(ICONS.trend, 14, 14)}
            <span>Potensi Kemandirian Warga</span>
            <div class="kemandirian-siap-badge" style="margin-left: 8px; font-size: 10px; background: rgba(16,185,129,0.12); color: var(--success); padding: 2px 6px; border-radius: 4px; font-weight: 700;">
              <span id="kemandirian-siap-exit">–</span> siap exit
            </div>
          </div>
          <button class="modal-close" onclick="document.getElementById('modal-premium-kemandirian').classList.remove('show')">
            <svg viewBox="0 0 24 24" width="13" height="13" stroke="currentColor" fill="none" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
          </button>
        </div>
        <div class="modal-body" style="padding: 16px; overflow-y: auto; flex: 1;">
          <div style="display:flex;gap:4px;margin-bottom:8px">
            <input type="text" id="kemandirian-search" class="form-control" placeholder="Cari nama warga..." style="font-size:11px;padding:6px;flex:1" oninput="FiturBaru.Kemandirian.renderSearch()">
            <select id="filter-kemandirian-status" class="form-control" style="font-size:11px;padding:5px;width:130px"
              onchange="FiturBaru.Kemandirian.load(this.value)">
              <option value="">Semua Status</option>
              <option value="mandiri">Mandiri / Siap Exit</option>
              <option value="berpotensi_mandiri">Berpotensi Mandiri</option>
              <option value="berkembang">Berkembang</option>
              <option value="bergantung">Bergantung</option>
              <option value="sangat_bergantung">Sangat Bergantung</option>
            </select>
          </div>

          <div id="kemandirian-list"><div class="fb-empty">Memuat data...</div></div>
        </div>
      </div>
    </div>`;
  }

  /* ─── Modal HTML ─── */
  function injectModals() {
    document.body.insertAdjacentHTML('beforeend', `
      <!-- Modal Verifikasi -->
      <div class="modal-overlay" id="modal-verifikasi">
        <div class="modal" style="width:400px">
          <div class="modal-header">
            <div class="modal-title">Catat Verifikasi Data</div>
            <button class="modal-close" onclick="document.getElementById('modal-verifikasi').classList.remove('show')">
              <svg viewBox="0 0 24 24" width="13" height="13" stroke="currentColor" fill="none" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
            </button>
          </div>
          <div class="modal-body">
            <input type="hidden" id="verif-modal-id">
            <div style="font-weight:600;color:var(--text-primary);margin-bottom:12px" id="verif-modal-nama"></div>
            <div class="form-group">
              <label class="form-label">Tanggal Verifikasi</label>
              <input type="date" id="verif-modal-tanggal" class="form-control">
            </div>
            <div class="form-group">
              <label class="form-label">Nama Petugas</label>
              <input type="text" id="verif-modal-petugas" class="form-control" placeholder="Nama petugas lapangan">
            </div>
            <div class="form-group">
              <label class="form-label">Catatan</label>
              <textarea id="verif-modal-catatan" class="form-control" rows="3" placeholder="Kondisi saat verifikasi..."></textarea>
            </div>
            <div class="verif-info-box">
              ${svgIcon(ICONS.shield,13,13)} Menyimpan verifikasi akan mereset skor kepercayaan data ke 100%.
            </div>
          </div>
          <div class="modal-footer">
            <button class="btn btn-ghost" onclick="document.getElementById('modal-verifikasi').classList.remove('show')">Batal</button>
            <button class="btn btn-primary" onclick="FiturBaru.Verifikasi.simpanVerifikasi()">
              ${svgIcon(ICONS.check2,12,12)} Simpan Verifikasi
            </button>
          </div>
        </div>
      </div>

      <!-- Modal Catatan Kemandirian -->
      <div class="modal-overlay" id="modal-kemandirian">
        <div class="modal" style="width:420px">
          <div class="modal-header">
            <div class="modal-title">Catatan Perkembangan Kemandirian</div>
            <button class="modal-close" onclick="document.getElementById('modal-kemandirian').classList.remove('show')">
              <svg viewBox="0 0 24 24" width="13" height="13" stroke="currentColor" fill="none" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
            </button>
          </div>
          <div class="modal-body">
            <input type="hidden" id="kemandirian-modal-id">
            <div style="font-weight:600;color:var(--text-primary);margin-bottom:12px" id="kemandirian-modal-nama"></div>
            <div class="form-group">
              <label class="form-label">Target Tanggal Exit Plan</label>
              <input type="date" id="kemandirian-modal-exit" class="form-control">
              <div class="form-hint">Kapan warga ini ditargetkan keluar dari program bantuan</div>
            </div>
            <div class="form-group">
              <label class="form-label">Catatan Perkembangan</label>
              <textarea id="kemandirian-modal-catatan" class="form-control" rows="4"
                placeholder="Perkembangan kondisi keluarga, pencapaian, rencana intervensi..."></textarea>
            </div>
          </div>
          <div class="modal-footer">
            <button class="btn btn-ghost" onclick="document.getElementById('modal-kemandirian').classList.remove('show')">Batal</button>
            <button class="btn btn-primary" onclick="FiturBaru.Kemandirian.simpanCatatan()">
              ${svgIcon(ICONS.check2,12,12)} Simpan Catatan
            </button>
          </div>
        </div>
      </div>
    `);
    
    // Modal Setujui Redistribusi
    document.body.insertAdjacentHTML('beforeend', `
      <div class="modal-overlay" id="modal-setujui-redistribusi">
        <div class="modal" style="width:450px">
          <div class="modal-header">
            <div class="modal-title">Setujui Redistribusi</div>
            <button class="modal-close" onclick="document.getElementById('modal-setujui-redistribusi').classList.remove('show')">
              <svg viewBox="0 0 24 24" width="13" height="13" stroke="currentColor" fill="none" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
            </button>
          </div>
          <div class="modal-body">
            <div style="font-weight:600;color:var(--text-primary);margin-bottom:4px" id="sr-penerima-nama">Masjid Penerima</div>
            <div style="font-size:11px;color:var(--text-muted);margin-bottom:12px">Menerima tambahan beban tanggungan (defisit kapasitas)</div>
            
            <input type="hidden" id="sr-penerima-id">
            <input type="hidden" id="sr-estimasi-dana-per-kk">
            <input type="hidden" id="sr-catatan-sistem">
            
            <div class="form-group">
              <label class="form-label">Alihkan Tanggungan Ke (Rumah Ibadah Surplus)</label>
              <select id="sr-pengirim-id" class="form-control"></select>
            </div>
            
            <div class="form-row">
              <div class="form-group" style="flex:1">
                <label class="form-label">Jumlah KK Dipindah</label>
                <input type="number" id="sr-jumlah-kk" class="form-control" readonly style="background:#f1f5f9; font-weight:bold;">
                <div class="form-hint">Dihitung otomatis dari warga yang dipilih.</div>
              </div>
              <div class="form-group" style="flex:1">
                <label class="form-label">Estimasi Dana</label>
                <input type="text" id="sr-estimasi-dana-display" class="form-control" readonly style="background:#f1f5f9">
                <input type="hidden" id="sr-estimasi-dana">
              </div>
            </div>
            
            <div class="form-group">
              <label class="form-label">Pilih Warga yang Dipindahkan <span style="font-weight:normal;color:#64748b;font-size:10px">(Otomatis rekomendasi sistem)</span></label>
              <div id="sr-warga-list-container" style="max-height:180px; overflow-y:auto; border:1px solid #e2e8f0; border-radius:6px; padding:8px; background:#fafafa; font-size:11px;">
                <div style="text-align:center; padding:10px; color:#94a3b8">Memuat warga...</div>
              </div>
            </div>

            <div class="form-group">
              <label class="form-label">Catatan Admin (Opsional)</label>
              <textarea id="sr-catatan" class="form-control" rows="2" placeholder="Tambahkan catatan keputusan..."></textarea>
            </div>
          </div>
          <div class="modal-footer">
            <button class="btn btn-ghost" onclick="document.getElementById('modal-setujui-redistribusi').classList.remove('show')">Batal</button>
            <button class="btn btn-primary" onclick="FiturBaru.Redistribusi.submitSetujui()">
              ${svgIcon(ICONS.check2,12,12)} Simpan Keputusan
            </button>
          </div>
        </div>
      </div>
    `);
  }

  function bindEvents() {
    // Keyboard close
    document.addEventListener('keydown', e => {
      if (e.key === 'Escape') {
        closeModal('modal-verifikasi');
        closeModal('modal-kemandirian');
        closeModal('modal-setujui-redistribusi');
        closeModal('modal-premium-redistribusi');
        closeModal('modal-premium-verifikasi');
        closeModal('modal-premium-kemandirian');
        closeModal('modal-kebutuhan-form');
        closeModal('modal-kontribusi-form');
        closeModal('modal-laporan-form');
        document.body.classList.remove('side-by-side-modals');
      }
    });

    document.getElementById('btn-kebutuhan-save')?.addEventListener('click', () => Kebutuhan.saveKebutuhan());
    document.getElementById('btn-kontribusi-save')?.addEventListener('click', () => Kebutuhan.saveDonation());
  }

  /* ─── Sub-tab switcher (global) ─── */
  window.switchFbTab = function(btn, prefix) {
    const tabId = btn.dataset.fbtab;
    const scope  = document.getElementById(`modal-premium-${prefix}`) || document.getElementById(`tab-${prefix}`);
    if (!scope) return;
    scope.querySelectorAll('.fb-sub-tab').forEach(b => b.classList.toggle('active', b.dataset.fbtab === tabId));
    scope.querySelectorAll('.fb-sub-panel').forEach(p => {
      p.classList.toggle('active', p.id === `${prefix}-${tabId}-wrap`);
    });
  };

  /* ══════════════════════════════════════════════════
     MODUL LAPORAN WARGA
  ══════════════════════════════════════════════════ */
  const Laporan = {
    async loadList() {
      const currentUser = App.getCurrentUser();
      if (!currentUser || currentUser.role === 'guest') return;

      const panel = document.getElementById('laporan-panel-content');
      if (!panel) return;

      const isAdminOrPetugas = currentUser.role === 'admin' || currentUser.role === 'petugas';

      try {
        const res = await fetch('api/laporan.php?_t=' + Date.now());
        const json = await res.json();
        
        if (!json.success) throw new Error(json.message);

        let petugasList = [];
        if (isAdminOrPetugas && json.petugas) {
          petugasList = json.petugas;
        }
        
        let html = '';

        if (isAdminOrPetugas) {
          html += `
            <div style="font-size:12px; font-weight:700; margin-bottom:10px; color:var(--text-primary); display:flex; justify-content:space-between; align-items:center;">
              <span>Daftar Laporan Warga Masuk <span style="font-size:10px; color:var(--text-muted); font-weight:500">(Total: ${json.total})</span></span>
              <select onchange="FiturBaru.Laporan.filterUI(this.value)" style="padding:4px 8px; font-size:11px; border-radius:4px; border:1px solid #d1d5db;">
                <option value="all">Semua Status</option>
                <option value="pending">Menunggu (${json.summary.pending || 0})</option>
                <option value="ditinjau">Sedang Ditinjau</option>
                <option value="diproses">Diproses Petugas</option>
                <option value="selesai">Selesai</option>
                <option value="ditolak">Ditolak</option>
              </select>
            </div>
          `;
        } else {
          html += `
            <div style="font-size:12px; font-weight:700; margin-bottom:10px; color:var(--text-primary);">
              Riwayat Laporan Saya
            </div>
          `;
        }

        if (!json.data || json.data.length === 0) {
          html += `<div class="empty-state">${svgIcon(ICONS.info, 28, 28)}<br>Belum ada laporan.</div>`;
          panel.innerHTML = html;
          return;
        }

        let listHtml = '<div class="data-list" id="laporan-data-list">';
        json.data.forEach(l => {
          const jenisLabel = {
            'warga_mampu': 'Warga Mampu',
            'data_tidak_sesuai': 'Data Tidak Sesuai',
            'warga_pindah': 'Warga Pindah',
            'warga_meninggal': 'Warga Meninggal',
            'data_ganda': 'Data Ganda',
            'lainnya': 'Lainnya'
          }[l.jenis_laporan] || l.jenis_laporan;

          const st = l.status;
          const statusBadge = `<span class="badge badge-laporan-${st}">${st.replace('_', ' ').toUpperCase()}</span>`;
          const pr = l.prioritas;
          const prioBadge = `<span class="badge badge-prioritas-${pr}">PRIORITAS ${pr.toUpperCase()}</span>`;

          const date = new Date(l.created_at).toLocaleDateString('id-ID', {day:'numeric', month:'short', year:'numeric', hour:'2-digit', minute:'2-digit'});
          
          let petugasOpts = '';
          petugasList.forEach(p => {
            petugasOpts += `<option value="${p}" ${l.ditugaskan_ke === p ? 'selected' : ''}>${p}</option>`;
          });

          listHtml += `
            <div class="laporan-card prioritas-${pr}" data-status="${st}">
              <div class="laporan-card-header">
                <div style="flex:1; min-width:0;">
                  <div class="laporan-card-nama">${l.nama_kepala_keluarga}</div>
                  <div class="laporan-card-meta">${l.kelurahan || '-'}, ${l.kecamatan || '-'}</div>
                </div>
                ${statusBadge}
              </div>
              <div class="laporan-card-jenis">${jenisLabel}</div>
              <div class="laporan-card-desc">" ${l.deskripsi} "</div>
              <div class="laporan-card-footer" style="display:flex; justify-content:space-between; align-items:center;">
                <div style="font-size:9px; color:var(--text-muted);">${date} • Oleh: ${l.pelapor_nama}</div>
                <div style="display:flex; gap:6px; align-items:center;">
                  ${prioBadge}
                  ${(l.ditugaskan_ke && st === 'diproses') ? `<span style="font-size:9px; color:#4f46e5; font-weight:700; background:#e0e7ff; padding:2px 6px; border-radius:12px; border:1px solid rgba(79,70,229,0.3);">👤 ${l.ditugaskan_ke}</span>` : ''}
                </div>
              </div>
          `;

          if (l.dokumentasi) {
            listHtml += `<div class="laporan-catatan-admin" style="background:#f0fdf4; border-color:#86efac; margin-top:5px;"><b>Link Dokumentasi Lapangan:</b> <a href="${l.dokumentasi}" target="_blank" style="color:#166534; text-decoration:underline; word-break:break-all;">${l.dokumentasi}</a></div>`;
          }

          if (isAdminOrPetugas) {
            listHtml += `
              <div class="laporan-admin-actions" style="margin-top:10px; display:flex; gap:8px;">
                <button class="btn btn-primary btn-xs" onclick="document.getElementById('lap-form-${l.id}').style.display='block'">Perbarui Status</button>
                ${currentUser.role === 'admin' ? `<button class="btn btn-danger btn-xs" onclick="FiturBaru.Laporan.hapus(${l.id})">Hapus</button>` : ''}
              </div>
              <div id="lap-form-${l.id}" style="display:none; margin-top:10px; background:#f9fafb; padding:10px; border-radius:6px; border:1px solid #e5e7eb;">
                <label style="font-size:10px; font-weight:600; color:#4b5563;">Status Laporan:</label>
                <select id="lap-status-${l.id}" style="width:100%; margin-bottom:8px; padding:6px; border-radius:4px; border:1px solid #d1d5db; font-size:11px;" onchange="if(this.value==='diproses'){document.getElementById('lap-petugas-wrap-${l.id}')?.style.setProperty('display', 'block');}else{document.getElementById('lap-petugas-wrap-${l.id}')?.style.setProperty('display', 'none');}">
                  <option value="pending" ${st==='pending'?'selected':''}>Menunggu</option>
                  <option value="ditinjau" ${st==='ditinjau'?'selected':''}>Sedang Ditinjau</option>
                  <option value="diproses" ${st==='diproses'?'selected':''}>Sedang Diproses (Petugas Lapangan)</option>
                  <option value="selesai" ${st==='selesai'?'selected':''}>Selesai / Terverifikasi</option>
                  <option value="ditolak" ${st==='ditolak'?'selected':''}>Ditolak / Tidak Valid</option>
                </select>
                ${currentUser.role === 'admin' ? `
                <div id="lap-petugas-wrap-${l.id}" style="display:${st==='diproses'?'block':'none'}; margin-bottom:8px;">
                  <label style="font-size:10px; font-weight:600; color:#4b5563;">Pilih Petugas:</label>
                  <select id="lap-petugas-${l.id}" style="width:100%; padding:6px; border-radius:4px; border:1px solid #d1d5db; font-size:11px;">
                    <option value="">-- Pilih Petugas --</option>
                    ${petugasOpts}
                  </select>
                </div>
                ` : ''}
                <label style="font-size:10px; font-weight:600; color:#4b5563;">Catatan / Tanggapan:</label>
                <input type="text" id="lap-catatan-${l.id}" placeholder="Tulis tanggapan atau catatan peninjauan..." value="${l.catatan_admin || ''}" style="width:100%; margin-bottom:8px; padding:6px; border-radius:4px; border:1px solid #d1d5db; font-size:11px;">
                <label style="font-size:10px; font-weight:600; color:#4b5563;">Upload Bukti Lapangan (Opsional):</label>
                <input type="file" id="lap-dokumentasi-${l.id}" accept="image/*,application/pdf" style="width:100%; margin-bottom:8px; padding:4px; border-radius:4px; border:1px solid #d1d5db; font-size:11px;">
                <div style="display:flex; justify-content:flex-end; gap:6px;">
                  <button class="btn btn-outline btn-xs" onclick="document.getElementById('lap-form-${l.id}').style.display='none'">Batal</button>
                  <button class="btn btn-success btn-xs" onclick="FiturBaru.Laporan.updateStatus(${l.id})">Simpan</button>
                </div>
              </div>
            `;
          }

          listHtml += `</div>`;
        });
        listHtml += '</div>';

        html += listHtml;
        panel.innerHTML = html;

      } catch (err) {
        panel.innerHTML = `<div class="empty-state">${svgIcon(ICONS.info, 28, 28)}<br>Gagal memuat laporan.</div>`;
      }
    },

    filterUI(status) {
      const cards = document.querySelectorAll('#laporan-data-list .laporan-card');
      cards.forEach(c => {
        if (status === 'all') c.style.display = 'block';
        else if (c.dataset.status === status) c.style.display = 'block';
        else c.style.display = 'none';
      });
    },

    bukaModalLaporan(wargaId, namaWarga) {
      document.getElementById('laporan-warga-id').value = wargaId;
      document.getElementById('laporan-warga-nama-display').textContent = 'Melaporkan Data: ' + namaWarga;
      document.getElementById('laporan-jenis').value = 'data_tidak_sesuai';
      document.getElementById('laporan-prioritas').value = 'sedang';
      document.getElementById('laporan-deskripsi').value = '';
      document.getElementById('modal-laporan-form').classList.add('show');
    },

    async submitLaporan() {
      const wargaId = document.getElementById('laporan-warga-id').value;
      const jenis = document.getElementById('laporan-jenis').value;
      const prioritas = document.getElementById('laporan-prioritas').value;
      const deskripsi = document.getElementById('laporan-deskripsi').value.trim();

      if (!deskripsi || deskripsi.length < 20) {
        showToast('Deskripsi wajib diisi minimal 20 karakter', 'error');
        return;
      }

      const btn = document.getElementById('btn-laporan-submit');
      btn.disabled = true;
      btn.innerHTML = 'Mengirim...';

      try {
        const res = await fetch('api/laporan.php', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            rumah_warga_id: wargaId,
            jenis_laporan: jenis,
            prioritas: prioritas,
            deskripsi: deskripsi
          })
        });
        const json = await res.json();
        
        if (json.success) {
          showToast(json.message, 'success');
          closeModal('modal-laporan-form');
          // Reload list jika sedang membuka tab laporan
          if (document.getElementById('tab-laporan')?.classList.contains('active')) {
            this.loadList();
          }
        } else {
          showToast(json.message || 'Gagal mengirim laporan', 'error');
        }
      } catch (err) {
        showToast('Terjadi kesalahan koneksi', 'error');
      } finally {
        btn.disabled = false;
        btn.innerHTML = `<svg viewBox="0 0 24 24" width="13" height="13" stroke="currentColor" fill="none" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg> Kirim Laporan`;
      }
    },

    async updateStatus(id) {
      const btn = event.currentTarget || event.target;
      const originalText = btn.innerHTML;
      btn.innerHTML = 'Menyimpan...';
      btn.disabled = true;
      
      const status = document.getElementById(`lap-status-${id}`).value;
      const catatanEl = document.getElementById(`lap-catatan-${id}`);
      const catatan = catatanEl ? catatanEl.value.trim() : '';
      
      const fileInput = document.getElementById(`lap-dokumentasi-${id}`);
      
      let ditugaskan_ke = '';
      const petugasSelect = document.getElementById(`lap-petugas-${id}`);
      if (petugasSelect && status === 'diproses') {
        ditugaskan_ke = petugasSelect.value;
      }

      const formData = new FormData();
      formData.append('_method', 'PUT');
      formData.append('id', id);
      formData.append('status', status);
      formData.append('catatan_admin', catatan);
      formData.append('ditugaskan_ke', ditugaskan_ke);
      
      if (fileInput && fileInput.files.length > 0) {
        formData.append('dokumentasi_file', fileInput.files[0]);
      }

      try {
        const res = await fetch('api/laporan.php', {
          method: 'POST',
          body: formData
        });
        const json = await res.json();
        
        if (json.success) {
          if (typeof showToast === 'function') showToast('Data berhasil diperbarui!', 'success');
          else alert('Data berhasil diperbarui!');
          this.loadList();
        } else {
          if (typeof showToast === 'function') showToast(json.message || 'Gagal memperbarui', 'error');
          else alert(json.message || 'Gagal memperbarui');
        }
      } catch (err) {
        if (typeof showToast === 'function') showToast('Terjadi kesalahan saat mengupdate', 'error');
        else alert('Terjadi kesalahan saat mengupdate');
      } finally {
        if (btn) {
          btn.innerHTML = originalText;
          btn.disabled = false;
        }
      }
    },

    async hapus(id) {
      if (!confirm('Apakah Anda yakin ingin menghapus laporan ini?')) return;
      try {
        const res = await fetch('api/laporan.php', {
          method: 'DELETE',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ id })
        });
        const json = await res.json();
        if (json.success) {
          showToast('Laporan dihapus', 'success');
          this.loadList();
        } else {
          showToast(json.message || 'Gagal menghapus', 'error');
        }
      } catch (err) {
        showToast('Terjadi kesalahan', 'error');
      }
    }
  };

  /* ══════════════════════════════════════════════════
     PUBLIC API
  ══════════════════════════════════════════════════ */
  return { init, Redistribusi, Verifikasi, Kemandirian, Kebutuhan, Laporan };
})();

// Expose FiturBaru globally
window.FiturBaru = FiturBaru;

document.addEventListener('DOMContentLoaded', () => FiturBaru.init());