/* ============================================================
   WebGIS â€” app.js
   Sistem Informasi Geografis Pengentasan Kemiskinan
============================================================ */
(function () {
'use strict';

/* â”€â”€ Konfigurasi â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
const DEFAULT_CENTER = [-0.05754868797441759, 109.32739998281652];
const DEFAULT_ZOOM   = 14;

/* â”€â”€ State Aplikasi â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
let clickTimer = null; // Timer untuk membedakan single click & double click
let mode = 'point';           // mode aktif saat ini
let deleteCallback = null;    // callback untuk konfirmasi hapus

// Preview sementara di peta
let previewMarker  = null;
let previewCircle  = null;
let previewLine    = null;
let previewPolygon = null;
let previewVertices = [];

// Data untuk drawing
let jalanLatLngs   = [];
let polygonLatLngs = [];

// Data runtime
let fasilitasPublikList = [];   // [{id, nama, lat, lng, radius}, ...]
let pendudukList    = [];   // [{data, marker}, ...]

/* â”€â”€ Layer Groups â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
let geoJalanLayer    = null;
let geoKecamatanLayer= null;
let geoSungaiLayer   = null;

const lgFasilitasPublik = L.layerGroup();
const lgPenduduk    = L.layerGroup();
const lgPoints      = L.layerGroup();
const lgJalan       = L.layerGroup();
const lgPolygon     = L.layerGroup();

/* â”€â”€ Inisialisasi Peta â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
const savedCenter = (() => {
  try { return JSON.parse(localStorage.getItem('webgis_center')); } catch { return null; }
})();
const savedZoom = parseInt(localStorage.getItem('webgis_zoom') || '0', 10) || DEFAULT_ZOOM;

const map = L.map('map', {
  doubleClickZoom: false,
  zoomControl: true
}).setView(savedCenter || DEFAULT_CENTER, savedZoom);

// Base tile
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
  maxZoom: 19,
  attribution: 'Â© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

// Scale control
L.control.scale({ imperial: false, metric: true, position: 'bottomleft' }).addTo(map);

// Simpan posisi peta
map.on('moveend zoomend', () => {
  const c = map.getCenter();
  localStorage.setItem('webgis_center', JSON.stringify([c.lat, c.lng]));
  localStorage.setItem('webgis_zoom', String(map.getZoom()));
});

// Sembunyikan loading setelah peta siap
map.whenReady(() => {
  setTimeout(() => el('mapLoading').classList.add('hidden'), 600);
});

/* â”€â”€ Tambahkan layer groups ke peta â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
[lgFasilitasPublik, lgPenduduk].forEach(lg => lg.addTo(map));
if (document.getElementById("layerTitik") && document.getElementById("layerTitik").checked) lgPoints.addTo(map);
if (document.getElementById("layerJalan") && document.getElementById("layerJalan").checked) lgJalan.addTo(map);
if (document.getElementById("layerPolygon") && document.getElementById("layerPolygon").checked) lgPolygon.addTo(map);

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   HELPER FUNCTIONS
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

function el(id) { return document.getElementById(id); }

function showToast(message, type = 'success', duration = 3500) {
  const container = el('toastContainer');
  const toast = document.createElement('div');
  const icons = { success: 'âœ“', error: 'âœ•', info: 'â„¹', warning: 'âš ' };
  toast.className = `toast ${type}`;
  toast.innerHTML = `<span>${icons[type] || 'â€¢'}</span><span>${message}</span>`;
  container.appendChild(toast);
  setTimeout(() => {
    toast.classList.add('fade-out');
    setTimeout(() => toast.remove(), 350);
  }, duration);
}

function showDeleteConfirm(message, callback) {
  el('deleteMessage').textContent = message;
  deleteCallback = callback;
  showModal('deleteModal');
}

function showModal(id) {
  el('modalBackdrop').classList.remove('hidden');
  el(id).classList.remove('hidden');
}

function hideModal(id) {
  el(id).classList.add('hidden');
  // sembunyikan backdrop hanya jika tidak ada modal lain terbuka
  const openModals = document.querySelectorAll('.modal:not(.hidden)');
  if (openModals.length === 0) {
    el('modalBackdrop').classList.add('hidden');
  }
}

function hideAllModals() {
  document.querySelectorAll('.modal').forEach(m => m.classList.add('hidden'));
  el('modalBackdrop').classList.add('hidden');
}

function setHelpText(text) {
  el('helpText').textContent = text;
}

/* â”€â”€ Kalkulasi Geospasial â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

function hitungPanjang(latlngs) {
  let total = 0;
  for (let i = 1; i < latlngs.length; i++) {
    total += latlngs[i - 1].distanceTo(latlngs[i]);
  }
  return total;
}

function hitungLuas(latlngs) {
  if (latlngs.length < 3) return 0;
  const pts = latlngs.map(ll => map.options.crs.project(ll));
  let area = 0;
  for (let i = 0, j = pts.length - 1; i < pts.length; j = i++) {
    area += (pts[j].x * pts[i].y) - (pts[i].x * pts[j].y);
  }
  return Math.abs(area / 2);
}

function getDistanceMeter(lat1, lng1, lat2, lng2) {
  return L.latLng(lat1, lng1).distanceTo(L.latLng(lat2, lng2));
}

function cekJangkauan(lat, lng) {
  let hasil = { status: 'Luar Jangkauan', id: '', nama: '' };
  fasilitasPublikList.forEach(ri => {
    const d = getDistanceMeter(lat, lng, parseFloat(ri.latitude), parseFloat(ri.longitude));
    if (d <= parseFloat(ri.radius)) {
      hasil = { status: 'Dalam Jangkauan', id: ri.id, nama: ri.nama };
    }
  });
  return hasil;
}

/* â”€â”€ GeoJSON helpers â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

function toLineFeature(latlngs, props = {}) {
  return {
    type: 'Feature',
    geometry: { type: 'LineString', coordinates: latlngs.map(ll => [ll.lng, ll.lat]) },
    properties: props
  };
}

function toPolygonFeature(latlngs, props = {}) {
  const ring = latlngs.map(ll => [ll.lng, ll.lat]);
  if (ring.length && (ring[0][0] !== ring[ring.length - 1][0] || ring[0][1] !== ring[ring.length - 1][1])) {
    ring.push([ring[0][0], ring[0][1]]);
  }
  return {
    type: 'Feature',
    geometry: { type: 'Polygon', coordinates: [ring] },
    properties: props
  };
}

function lineFeatureToLatLngs(feat) {
  if (!feat?.geometry?.coordinates) return [];
  return feat.geometry.coordinates.map(c => [c[1], c[0]]);
}

function polygonFeatureToLatLngs(feat) {
  if (!feat?.geometry?.coordinates?.[0]) return [];
  const ring = [...feat.geometry.coordinates[0]];
  if (ring.length > 1) {
    const f = ring[0], l = ring[ring.length - 1];
    if (f[0] === l[0] && f[1] === l[1]) ring.pop();
  }
  return ring.map(c => [c[1], c[0]]);
}

/* â”€â”€ Warna Helper â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

function warnaJalan(status) {
  return { 'Jalan Nasional': '#d32f2f', 'Jalan Provinsi': '#f57c00', 'Jalan Kabupaten': '#388e3c' }[status] || '#1565c0';
}

function warnaPolygon(status) {
  return { 'SHM': '#1b5e20', 'HGB': '#1565c0', 'HGU': '#ef6c00', 'HP': '#6a1b9a' }[status] || '#455a64';
}

function warnaKecamatan(nama) {
  const colors = {
    'Pontianak Barat': '#e41a1c', 'Pontianak Timur': '#377eb8',
    'Pontianak Utara': '#4daf4a', 'Pontianak Selatan': '#984ea3',
    'Pontianak Kota': '#ff7f00', 'Pontianak Tenggara': '#a65628'
  };
  return colors[nama] || '#888888';
}

/* â”€â”€ Custom Marker Icons â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */

function createFPIcon() {
  return L.divIcon({
    className: '',
    html: `<div style="
      width:28px;height:28px;
      background:#e53935;
      border:3px solid white;
      border-radius:50% 50% 50% 0;
      transform:rotate(-45deg);
      box-shadow:0 3px 10px rgba(229,57,53,0.5);
    "></div>`,
    iconSize: [28, 28],
    iconAnchor: [14, 28],
    popupAnchor: [0, -30]
  });
}

function createPointIcon(is24) {
  const color = is24 ? '#4f8ef7' : '#78909c';
  return L.divIcon({
    className: '',
    html: `<div style="
      width:24px;height:24px;
      background:${color};
      border:3px solid white;
      border-radius:50%;
      box-shadow:0 2px 8px rgba(0,0,0,0.35);
    "></div>`,
    iconSize: [24, 24],
    iconAnchor: [12, 12],
    popupAnchor: [0, -14]
  });
}

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   PREVIEW MANAGEMENT
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

function clearAllPreview() {
  if (previewMarker)  { map.removeLayer(previewMarker);  previewMarker  = null; }
  if (previewCircle)  { map.removeLayer(previewCircle);  previewCircle  = null; }
  if (previewLine)    { map.removeLayer(previewLine);    previewLine    = null; }
  if (previewPolygon) { map.removeLayer(previewPolygon); previewPolygon = null; }
  previewVertices.forEach(v => map.removeLayer(v));
  previewVertices = [];
  jalanLatLngs   = [];
  polygonLatLngs = [];
}

function addVertexMarker(latlng, color = '#1565c0') {
  const v = L.circleMarker(latlng, {
    radius: 5, color, fillColor: color,
    fillOpacity: 1, weight: 2
  }).addTo(map);
  previewVertices.push(v);
  return v;
}

function updateJalanPreview() {
  if (previewLine)    { map.removeLayer(previewLine); previewLine = null; }
  previewVertices.forEach(v => map.removeLayer(v));
  previewVertices = [];

  jalanLatLngs.forEach((ll, i) => {
    const v = addVertexMarker(ll, '#d32f2f');
    v.bindTooltip(`Titik ${i + 1}`, { direction: 'top', permanent: false });
  });

  if (jalanLatLngs.length >= 2) {
    previewLine = L.polyline(jalanLatLngs, { color: '#d32f2f', weight: 4, opacity: 0.9 }).addTo(map);
    el('panjang_meter').value = hitungPanjang(jalanLatLngs).toFixed(2);
  }
  el('jumlah_titik_jalan').value = jalanLatLngs.length;
  el('koordinat_jalan').value = JSON.stringify(toLineFeature(jalanLatLngs), null, 2);
}

function updatePolygonPreview() {
  if (previewPolygon) { map.removeLayer(previewPolygon); previewPolygon = null; }
  previewVertices.forEach(v => map.removeLayer(v));
  previewVertices = [];

  polygonLatLngs.forEach((ll, i) => {
    const v = addVertexMarker(ll, '#6a1b9a');
    v.bindTooltip(`Titik ${i + 1}`, { direction: 'top', permanent: false });
  });

  if (polygonLatLngs.length >= 3) {
    previewPolygon = L.polygon(polygonLatLngs, {
      color: '#6a1b9a', fillColor: '#ba68c8', fillOpacity: 0.3, weight: 3
    }).addTo(map);
    el('luas_tanah').value = hitungLuas(polygonLatLngs).toFixed(4);
  }
  el('jumlah_titik_polygon').value = polygonLatLngs.length;
  el('koordinat_polygon').value = JSON.stringify(toPolygonFeature(polygonLatLngs), null, 2);
}

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   MODE MANAGEMENT
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

const MODES = {
  point:          { btn: 'btnToolPoint',      help: 'Klik pada peta untuk menambah titik.' },
  jalan:          { btn: 'btnToolJalan',      help: 'Klik titik-titik jalan. Double-klik untuk selesai. Klik-kanan untuk hapus titik terakhir.' },
  polygon:        { btn: 'btnToolPolygon',    help: 'Klik titik-titik polygon. Double-klik untuk selesai. Klik-kanan untuk hapus titik terakhir.' },
  fasilitas_publik:   { btn: 'btnToolFasilitasPublik',help: 'Klik pada peta untuk menentukan lokasi Fasilitas Publik.' },
  penduduk_miskin:{ btn: 'btnToolPenduduk',   help: 'Klik pada peta untuk menentukan lokasi penduduk miskin.' },
  lokasi:         { btn: 'btnToolLokasi',     help: 'Mencari lokasi Anda...' },
};

function setMode(newMode) {
  clearAllPreview();
  hideAllModals();

  mode = newMode;

  // Update active button
  document.querySelectorAll('.tool-btn').forEach(b => b.classList.remove('active'));
  const cfg = MODES[newMode];
  if (cfg) {
    const btn = el(cfg.btn);
    if (btn) btn.classList.add('active');
    setHelpText(cfg.help);
  }

  // Khusus lokasi: langsung trigger
  if (newMode === 'lokasi') {
    map.locate({ setView: true, maxZoom: 18 });
    mode = 'point'; // kembali ke point setelah locate
    el('btnToolPoint').classList.add('active');
    el('btnToolLokasi').classList.remove('active');
  }
}

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   RENDER FUNCTIONS
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

/* â”€â”€ Render Point (SPBU) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
function renderPoint(item) {
  const lat = parseFloat(item.latitude);
  const lng = parseFloat(item.longitude);
  const is24 = item.buka_24_jam === 'Ya';

  const marker = L.marker([lat, lng], { icon: createPointIcon(is24) }).addTo(lgPoints);

  const popup = `
    <div class="popup-card">
      <div class="popup-title">ðŸ“ ${item.nama}</div>
      <div class="popup-row"><strong>No. WA</strong><span>${item.no_wa}</span></div>
      <div class="popup-row"><strong>24 Jam</strong><span>${item.buka_24_jam}</span></div>
    </div>
    <div class="popup-actions">
      <button class="popup-btn del" onclick="hapusData('point',${item.id},'Hapus titik ${item.nama}?')">ðŸ—‘ Hapus</button>
    </div>`;

  marker.bindPopup(popup, { maxWidth: 280 });
  return marker;
}

/* â”€â”€ Render Jalan â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
function renderJalan(item) {
  try {
    const feat = JSON.parse(item.koordinat);
    const coords = lineFeatureToLatLngs(feat);
    const poly = L.polyline(coords, {
      color: warnaJalan(item.status_jalan), weight: 5, opacity: 0.85
    }).addTo(lgJalan);

    const popup = `
      <div class="popup-card">
        <div class="popup-title">ðŸ›£ï¸ ${item.nama_jalan}</div>
        <div class="popup-row"><strong>Status</strong><span>${item.status_jalan}</span></div>
        <div class="popup-row"><strong>Panjang</strong><span>${parseFloat(item.panjang_meter).toFixed(1)} m</span></div>
      </div>
      <div class="popup-actions">
        <button class="popup-btn del" onclick="hapusData('jalan',${item.id},'Hapus jalan ${item.nama_jalan}?')">ðŸ—‘ Hapus</button>
      </div>`;

    poly.bindPopup(popup, { maxWidth: 280 });
    return poly;
  } catch (e) { console.error('renderJalan error:', e); }
}

/* â”€â”€ Render Polygon â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
function renderPolygon(item) {
  try {
    const feat = JSON.parse(item.koordinat);
    const coords = polygonFeatureToLatLngs(feat);
    const warna = warnaPolygon(item.status_kepemilikan);
    const poly = L.polygon(coords, {
      color: warna, fillColor: warna, fillOpacity: 0.3, weight: 3
    }).addTo(lgPolygon);

    const popup = `
      <div class="popup-card">
        <div class="popup-title">â¬  ${item.nama_parsil}</div>
        <div class="popup-row"><strong>Status</strong><span>${item.status_kepemilikan}</span></div>
        <div class="popup-row"><strong>Luas</strong><span>${parseFloat(item.luas_tanah).toFixed(2)} mÂ²</span></div>
      </div>
      <div class="popup-actions">
        <button class="popup-btn del" onclick="hapusData('polygon',${item.id},'Hapus polygon ${item.nama_parsil}?')">ðŸ—‘ Hapus</button>
      </div>`;

    poly.bindPopup(popup, { maxWidth: 280 });
    return poly;
  } catch (e) { console.error('renderPolygon error:', e); }
}

/* â”€â”€ Render Fasilitas Publik â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
function renderFasilitasPublik(item) {
  const lat = parseFloat(item.latitude);
  const lng = parseFloat(item.longitude);
  const radius = parseFloat(item.radius);

  fasilitasPublikList.push(item);

  const marker = L.marker([lat, lng], { icon: createFPIcon() }).addTo(lgFasilitasPublik);
  const circle = L.circle([lat, lng], {
    radius, color: '#e53935', fillColor: '#ef9a9a',
    fillOpacity: 0.12, weight: 2, dashArray: '6 4'
  }).addTo(lgFasilitasPublik);

  const popup = `
    <div class="popup-card">
      <div class="popup-title">
        ðŸ•Œ ${item.nama}
        <span class="popup-badge badge-fp">${item.jenis || 'Fasilitas Publik'}</span>
      </div>
      <div class="popup-row"><strong>Alamat</strong><span>${item.alamat || '-'}</span></div>
      <div class="popup-row"><strong>Radius</strong><span>${radius} m</span></div>
      <div class="popup-row"><strong>Kontak</strong><span>${item.kontak || '-'}</span></div>
    </div>
    <div class="popup-actions">
      <button class="popup-btn" onclick="editFasilitasPublik(${item.id})">âœ Edit</button>
      <button class="popup-btn del" onclick="hapusData('fasilitas_publik',${item.id},'Hapus ${item.nama}?')">ðŸ—‘ Hapus</button>
    </div>`;

  marker.bindPopup(popup, { maxWidth: 300 });
  circle.bindPopup(popup, { maxWidth: 300 });

  return { marker, circle };
}

/* â”€â”€ Render Penduduk Miskin â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
function renderPenduduk(item) {
  const lat = parseFloat(item.latitude);
  const lng = parseFloat(item.longitude);
  const cek  = cekJangkauan(lat, lng);

  const warna = cek.status === 'Dalam Jangkauan' ? '#e53935' : '#2e7d32';
  const fillW = cek.status === 'Dalam Jangkauan' ? '#ef5350' : '#43a047';

  const marker = L.circleMarker([lat, lng], {
    radius: 8, color: warna, fillColor: fillW,
    fillOpacity: 0.85, weight: 2
  }).addTo(lgPenduduk);

  const badgeClass = cek.status === 'Dalam Jangkauan' ? 'badge-dalam' : 'badge-luar';
  const popup = `
    <div class="popup-card">
      <div class="popup-title">
        ðŸ‘¤ ${item.nama}
        <span class="popup-badge ${badgeClass}">${cek.status}</span>
      </div>
      <div class="popup-row"><strong>NIK</strong><span>${item.nik || '-'}</span></div>
      <div class="popup-row"><strong>Ditangani</strong><span>${cek.nama || item.fp_nama || '-'}</span></div>
      <div class="popup-row"><strong>Keterangan</strong><span>${item.keterangan || '-'}</span></div>
    </div>
    <div class="popup-actions">
      <button class="popup-btn" onclick="editPenduduk(${item.id})">âœ Edit</button>
      <button class="popup-btn del" onclick="hapusData('penduduk_miskin',${item.id},'Hapus data ${item.nama}?')">ðŸ—‘ Hapus</button>
    </div>`;

  marker.bindPopup(popup, { maxWidth: 300 });

  pendudukList.push({ data: item, marker });
  return marker;
}

/* â”€â”€ Refresh Status Penduduk â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
function refreshStatusPenduduk() {
  lgPenduduk.clearLayers();
  const backup = pendudukList.map(p => p.data);
  pendudukList = [];
  backup.forEach(item => renderPenduduk(item));
  updateDashboardStats(); // Panggil fungsi update stat
}

/* â”€â”€ Update Statistik Dashboard Secara Real-Time â”€â”€â”€â”€â”€â”€â”€â”€ */
function updateDashboardStats() {
  const totalFP = fasilitasPublikList.length;
  const totalPM = pendudukList.length;
  
  let ditangani = 0;
  pendudukList.forEach(p => {
    const cek = cekJangkauan(parseFloat(p.data.latitude), parseFloat(p.data.longitude));
    if (cek.status === 'Dalam Jangkauan') ditangani++;
  });
  
  const belum = totalPM - ditangani;
  const persen = totalPM > 0 ? ((ditangani / totalPM) * 100).toFixed(1) : 0;

  // Update angka di HTML
  if (el('statTotalRI')) el('statTotalRI').textContent = totalFP;
  if (el('statTotalPM')) el('statTotalPM').textContent = totalPM;
  if (el('statDitangani')) el('statDitangani').textContent = ditangani;
  if (el('statBelum')) el('statBelum').textContent = belum;
  if (el('statPersen')) el('statPersen').textContent = persen + '%';
  if (el('statProgressBar')) el('statProgressBar').style.width = persen + '%';
}
/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   LOAD DATA AWAL
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
(APP_DATA.points || []).forEach(renderPoint);
(APP_DATA.jalan  || []).forEach(renderJalan);
(APP_DATA.polygons || []).forEach(renderPolygon);
(APP_DATA.fasilitasPublik || []).forEach(renderFasilitasPublik);
(APP_DATA.pendudukMiskin || []).forEach(renderPenduduk);

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   LOAD GEOJSON EKSTERNAL
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

function loadGeoJSON(url, options = {}) {
  return fetch(url)
    .then(r => { if (!r.ok) throw new Error('Gagal load: ' + url); return r.json(); })
    .then(geojson => {
      const layer = L.geoJSON(geojson, {
        style: feat => {
          const t = feat.geometry?.type || '';
          if (t === 'Polygon' || t === 'MultiPolygon') {
            let fill = options.fillColor || '#42a5f5';
            if (options.dynamicColor && feat.properties) {
              const nm = feat.properties.Ket || feat.properties.WADMKC ||
                         feat.properties.KECAMATAN || feat.properties.nama || '';
              fill = warnaKecamatan(nm);
            }
            return { color: '#333', weight: 1.5, fillColor: fill, fillOpacity: 0.35 };
          }
          if (t === 'LineString' || t === 'MultiLineString') {
            return { color: options.color || '#1565c0', weight: options.weight || 2, opacity: 0.9 };
          }
          return { color: options.color || '#1565c0' };
        },
        pointToLayer: (feat, latlng) => L.circleMarker(latlng, {
          radius: 4, color: options.color || '#1565c0',
          fillColor: options.fillColor || '#42a5f5', fillOpacity: 0.9, weight: 1
        }),
        onEachFeature: (feat, layer) => {
          if (!feat.properties) return;
          let html = `<div class="popup-card"><div class="popup-title">${options.title || 'GeoJSON'}</div>`;
          Object.entries(feat.properties).forEach(([k, v]) => {
            if (v) html += `<div class="popup-row"><strong>${k}</strong><span>${v}</span></div>`;
          });
          html += '</div>';
          layer.bindPopup(html, { maxWidth: 280 });
        }
      });

      if (options.adjustWeight) {
        map.on('zoomend', () => {
          const z = map.getZoom();
          const w = z <= 12 ? 0.8 : z <= 14 ? 1.5 : z <= 16 ? 2 : 3;
          layer.setStyle({ weight: w });
        });
      }

      if (options.addToMap !== false) { layer.addTo(map); if (options.fitBounds) map.fitBounds(layer.getBounds()); } return layer;
    })
    .catch(err => { console.warn(err.message); return null; });
}

Promise.all([
  loadGeoJSON('data/Sungai_Besar.geojson', {
    title: 'Sungai Besar', color: '#0d47a1', fillColor: '#90caf9',
    weight: 2, fitBounds: false, addToMap: el('layerSungai') && el('layerSungai').checked
  }),
  loadGeoJSON('data/admin_kecamatan.geojson', {
    title: 'Admin Kecamatan', dynamicColor: true,
    color: '#ef6c00', weight: 1.5, fitBounds: false, addToMap: el('layerKecamatan') && el('layerKecamatan').checked
  }),
  loadGeoJSON('data/Jaringan_Jalan.geojson', {
    title: 'Jaringan Jalan', color: '#d32f2f',
    weight: 1.5, fitBounds: false, adjustWeight: true, addToMap: el('layerGeoJalan') && el('layerGeoJalan').checked
  })
]).then(([sungai, kecamatan, jalan]) => {
  geoSungaiLayer    = sungai;
  geoKecamatanLayer = kecamatan;
  geoJalanLayer = jalan; if (el('layerSungai') && !el('layerSungai').checked) map.removeLayer(geoSungaiLayer); if (el('layerKecamatan') && !el('layerKecamatan').checked) map.removeLayer(geoKecamatanLayer); if (el('layerGeoJalan') && !el('layerGeoJalan').checked) map.removeLayer(geoJalanLayer); });

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   REVERSE GEOCODING
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

function reverseGeocode(lat, lng) {
  el('fp_alamat').value = '';
  el('geocodeStatus').textContent = 'â³ Mencari alamat...';

  fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}&accept-language=id`)
    .then(r => r.json())
    .then(data => {
      el('fp_alamat').value = data.display_name || 'Alamat tidak ditemukan';
      el('geocodeStatus').textContent = 'âœ“';
      setTimeout(() => { el('geocodeStatus').textContent = ''; }, 2000);
    })
    .catch(() => {
      el('fp_alamat').value = 'Gagal mengambil alamat';
      el('geocodeStatus').textContent = 'âœ•';
    });
}

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   MAP EVENT HANDLERS
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

map.on('click', e => {
  const { lat, lng } = e.latlng;

  // Mode yang tidak perlu timer (langsung eksekusi)
  if (mode === 'point') {
    clearAllPreview();
    el('point_id').value = '';
    el('point_nama').value = '';
    el('point_no_wa').value = '';
    el('point_latitude').value = lat.toFixed(10);
    el('point_longitude').value = lng.toFixed(10);
    document.querySelector('input[name="point_buka_24_jam"][value="Tidak"]').checked = true;
    el('pointModalTitle').textContent = 'Tambah Titik';

    previewMarker = L.marker(e.latlng, { icon: createPointIcon(false) }).addTo(map);
    showModal('pointModal');
    return;
  }

  if (mode === 'fasilitas_publik') {
    el('fp_id').value = '';
    el('fp_nama').value = '';
    el('fp_jenis').value = 'Masjid';
    el('fp_kontak').value = '';
    el('fp_radius').value = 300;
    el('fp_radius_text').textContent = '300';
    el('fp_latitude').value  = lat.toFixed(10);
    el('fp_longitude').value = lng.toFixed(10);
    el('fpModalTitle').textContent = 'Tambah Fasilitas Publik';

    if (previewMarker) map.removeLayer(previewMarker);
    if (previewCircle) map.removeLayer(previewCircle);
    previewMarker = L.marker(e.latlng, { icon: createFPIcon() }).addTo(map);
    previewCircle = L.circle(e.latlng, {
      radius: 300, color: '#e53935', fillColor: '#ef9a9a',
      fillOpacity: 0.12, weight: 2, dashArray: '6 4'
    }).addTo(map);

    reverseGeocode(lat, lng);
    showModal('fasilitasPublikModal');
    return;
  }

  if (mode === 'penduduk_miskin') {
    el('pm_id').value = '';
    el('pm_nama').value = '';
    el('pm_nik').value = '';
    el('pm_keterangan').value = '';
    el('pm_latitude').value  = lat.toFixed(10);
    el('pm_longitude').value = lng.toFixed(10);
    el('pmModalTitle').textContent = 'Tambah Penduduk Miskin';

    const cek = cekJangkauan(lat, lng);
    updateStatusJangkauan(cek);

    if (previewMarker) map.removeLayer(previewMarker);
    const warna = cek.status === 'Dalam Jangkauan' ? '#e53935' : '#2e7d32';
    previewMarker = L.circleMarker(e.latlng, {
      radius: 8, color: warna, fillColor: warna, fillOpacity: 0.85, weight: 2
    }).addTo(map);

    showModal('pendudukModal');
    return;
  }

  // Khusus mode Menggambar (Jalan & Polygon), gunakan Timer
  if (mode === 'jalan' || mode === 'polygon') {
    if (clickTimer) clearTimeout(clickTimer); // Hapus timer lama jika ada klik berdekatan
    
    clickTimer = setTimeout(() => {
      // Eksekusi jika benar-benar single-click
      if (mode === 'jalan') {
        jalanLatLngs.push(e.latlng);
        updateJalanPreview();
      } else if (mode === 'polygon') {
        polygonLatLngs.push(e.latlng);
        updatePolygonPreview();
      }
    }, 250); // Delay 250 milidetik
  }
});

map.on('dblclick', () => {
  if (clickTimer) {
    clearTimeout(clickTimer); // Batalkan single-click jika terdeteksi double-click
    clickTimer = null;
  }

  if (mode === 'jalan') {
    if (jalanLatLngs.length < 2) { showToast('Minimal 2 titik untuk jalan.', 'warning'); return; }
    updateJalanPreview();
    showModal('jalanModal');
  }
  if (mode === 'polygon') {
    if (polygonLatLngs.length < 3) { showToast('Minimal 3 titik untuk polygon.', 'warning'); return; }
    updatePolygonPreview();
    showModal('polygonModal');
  }
});

map.on('contextmenu', () => {
  if (mode === 'jalan' && jalanLatLngs.length > 0) {
    jalanLatLngs.pop(); updateJalanPreview(); return;
  }
  if (mode === 'polygon' && polygonLatLngs.length > 0) {
    polygonLatLngs.pop(); updatePolygonPreview(); return;
  }
  if (mode === 'point') {
    clearAllPreview();
    hideModal('pointModal');
  }
});

map.on('locationfound', e => {
  showToast('Lokasi ditemukan!', 'success');
  L.marker(e.latlng)
    .addTo(map)
    .bindPopup('<div class="popup-card"><div class="popup-title">ðŸ“¡ Lokasi Saya</div></div>')
    .openPopup();
});

map.on('locationerror', () => {
  showToast('Tidak dapat mengakses lokasi. Pastikan izin lokasi browser aktif.', 'error');
});

document.addEventListener('keydown', e => {
  if (e.key === 'Escape') { clearAllPreview(); hideAllModals(); }
});

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   STATUS JANGKAUAN UI
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
function updateStatusJangkauan(cek) {
  const elStatus    = el('pm_status');
  const elDitangani = el('pm_ditangani');
  elStatus.textContent = cek.status;
  elStatus.className = 'sj-value ' + (cek.status === 'Dalam Jangkauan' ? 'dalam' : 'luar');
  elDitangani.textContent = cek.nama ? `Ditangani oleh: ${cek.nama}` : 'Tidak dalam jangkauan Fasilitas Publik manapun.';
}

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   TOOL BUTTONS
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
document.querySelectorAll('.tool-btn').forEach(btn => {
  btn.addEventListener('click', () => {
    const m = btn.dataset.mode;
    if (m) setMode(m);
  });
});

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   SIDEBAR TOGGLE
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
const sidebar       = el('sidebar');
const mapContainer  = el('mapContainer');
const sidebarOpenBtn= el('sidebarOpenBtn');
const isMobile      = () => window.innerWidth <= 680;

el('sidebarToggle').addEventListener('click', () => {
  if (isMobile()) {
    sidebar.classList.toggle('mobile-open');
  } else {
    sidebar.classList.toggle('collapsed');
    mapContainer.classList.toggle('full-width');
    sidebarOpenBtn.classList.toggle('hidden');
    map.invalidateSize();
  }
});

sidebarOpenBtn.addEventListener('click', () => {
  sidebar.classList.remove('collapsed');
  mapContainer.classList.remove('full-width');
  sidebarOpenBtn.classList.add('hidden');
  map.invalidateSize();
});

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   LAYER CHECKBOXES
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
function bindLayerToggle(checkboxId, layerGroup) {
  const cb = el(checkboxId);
  if (!cb) return;
  cb.addEventListener('change', () => {
    if (cb.checked) {
      if (!map.hasLayer(layerGroup)) layerGroup.addTo(map);
    } else {
      map.removeLayer(layerGroup);
    }
  });
}

bindLayerToggle('layerFasilitasPublik',  lgFasilitasPublik);
bindLayerToggle('layerPendudukDalam', lgPenduduk);
bindLayerToggle('layerPendudukLuar',  lgPenduduk);

bindLayerToggle("layerTitik", lgPoints);
bindLayerToggle("layerJalan", lgJalan);
bindLayerToggle("layerPolygon", lgPolygon);

el('layerGeoJalan').addEventListener('change', function () {
  if (geoJalanLayer) { this.checked ? geoJalanLayer.addTo(map) : map.removeLayer(geoJalanLayer); }
});
el('layerKecamatan').addEventListener('change', function () {
  if (geoKecamatanLayer) { this.checked ? geoKecamatanLayer.addTo(map) : map.removeLayer(geoKecamatanLayer); }
});
el('layerSungai').addEventListener('change', function () {
  if (geoSungaiLayer) { this.checked ? geoSungaiLayer.addTo(map) : map.removeLayer(geoSungaiLayer); }
});

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   RADIUS SLIDER â†’ PREVIEW
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
el('fp_radius').addEventListener('input', function () {
  const r = parseInt(this.value, 10);
  el('fp_radius_text').textContent = r;
  if (previewCircle) previewCircle.setRadius(r);
});

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   MODAL CLOSE BUTTONS
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
[
  ['closePointModal',       'pointModal'],
  ['cancelPointModal',      'pointModal'],
  ['closeJalanModal',       'jalanModal'],
  ['cancelJalanModal',      'jalanModal'],
  ['closePolygonModal',     'polygonModal'],
  ['cancelPolygonModal',    'polygonModal'],
  ['closefasilitasPublikModal', 'fasilitasPublikModal'],
  ['cancelfasilitasPublikModal','fasilitasPublikModal'],
  ['closePendudukModal',    'pendudukModal'],
  ['cancelPendudukModal',   'pendudukModal'],
].forEach(([btnId, modalId]) => {
  const btn = el(btnId);
  if (btn) btn.addEventListener('click', () => {
    hideModal(modalId);
    clearAllPreview();
  });
});

el('modalBackdrop').addEventListener('click', () => {
  hideAllModals();
  clearAllPreview();
});

/* Konfirmasi hapus */
el('confirmDelete').addEventListener('click', () => {
  if (typeof deleteCallback === 'function') deleteCallback();
  hideModal('deleteModal');
  deleteCallback = null;
});
el('cancelDelete').addEventListener('click', () => {
  hideModal('deleteModal');
  deleteCallback = null;
});

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   SAVE: POINT
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
el('btnSavePoint').addEventListener('click', () => {
  const nama  = el('point_nama').value.trim();
  const no_wa = el('point_no_wa').value.trim();
  const radio = document.querySelector('input[name="point_buka_24_jam"]:checked');
  const lat   = el('point_latitude').value.trim();
  const lng   = el('point_longitude').value.trim();

  if (!nama || !no_wa || !radio || !lat || !lng) {
    showToast('Semua field wajib diisi dan lokasi harus dipilih.', 'error'); return;
  }

  const id  = el('point_id').value;
  const url = id ? 'point/update.php' : 'point/simpan.php';

  const fd = new FormData();
  if (id) fd.append('id', id);
  fd.append('nama', nama);
  fd.append('no_wa', no_wa);
  fd.append('buka_24_jam', radio.value);
  fd.append('latitude', lat);
  fd.append('longitude', lng);

  postData(url, fd).then(res => {
    if (res.status === 'success') {
      if (previewMarker) map.removeLayer(previewMarker);
      
      if (id) {
        const idx = APP_DATA.points.findIndex(x => String(x.id) === String(id));
        if (idx > -1) APP_DATA.points[idx] = res.data;
        lgPoints.clearLayers();
        APP_DATA.points.forEach(renderPoint);
      } else {
        APP_DATA.points.push(res.data);
        renderPoint(res.data);
      }

      hideModal('pointModal');
      showToast(id ? 'Titik berhasil diperbarui.' : 'Titik berhasil disimpan.');
    } else {
      showToast(res.message || 'Gagal menyimpan titik.', 'error');
    }
  });
});

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   SAVE: JALAN
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
el('btnSaveJalan').addEventListener('click', () => {
  const nama   = el('nama_jalan').value.trim();
  const status = el('status_jalan').value;
  const panjang = el('panjang_meter').value;
  const koordinat = el('koordinat_jalan').value.trim();

  if (!nama || !status) { showToast('Nama dan status jalan wajib diisi.', 'error'); return; }
  if (jalanLatLngs.length < 2) { showToast('Minimal 2 titik untuk jalan.', 'error'); return; }

  const fd = new FormData();
  fd.append('nama_jalan', nama);
  fd.append('status_jalan', status);
  fd.append('panjang_meter', panjang || '0');
  fd.append('koordinat', koordinat);

  postData('jalan/simpan.php', fd).then(res => {
    if (res.status === 'success') {
      clearAllPreview();
      APP_DATA.jalan.push(res.data); // Sinkronisasi array lokal
      renderJalan(res.data);
      hideModal('jalanModal');
      el('nama_jalan').value = '';
      el('status_jalan').value = '';
      showToast('Jalan berhasil disimpan.');
    } else {
      showToast(res.message || 'Gagal menyimpan jalan.', 'error');
    }
  });
});

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   SAVE: POLYGON
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
el('btnSavePolygon').addEventListener('click', () => {
  const nama   = el('nama_parsil').value.trim();
  const status = el('status_kepemilikan').value;
  const luas   = el('luas_tanah').value;
  const koordinat = el('koordinat_polygon').value.trim();

  if (!nama || !status) { showToast('Nama dan status kepemilikan wajib diisi.', 'error'); return; }
  if (polygonLatLngs.length < 3) { showToast('Minimal 3 titik untuk polygon.', 'error'); return; }

  const fd = new FormData();
  fd.append('nama_parsil', nama);
  fd.append('status_kepemilikan', status);
  fd.append('luas_tanah', luas || '0');
  fd.append('koordinat', koordinat);

  postData('polygon/simpan.php', fd).then(res => {
    if (res.status === 'success') {
      clearAllPreview();
      APP_DATA.polygons.push(res.data); // Sinkronisasi array lokal
      renderPolygon(res.data);
      hideModal('polygonModal');
      el('nama_parsil').value = '';
      el('status_kepemilikan').value = '';
      showToast('Polygon berhasil disimpan.');
    } else {
      showToast(res.message || 'Gagal menyimpan polygon.', 'error');
    }
  });
});

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   SAVE: Fasilitas Publik
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
el('btnSaveFasilitasPublik').addEventListener('click', () => {
  const nama  = el('fp_nama').value.trim();
  const lat   = el('fp_latitude').value.trim();
  const lng   = el('fp_longitude').value.trim();

  if (!nama) { showToast('Nama Fasilitas Publik wajib diisi.', 'error'); return; }
  if (!lat || !lng) { showToast('Klik pada peta untuk menentukan lokasi.', 'error'); return; }

  const id  = el('fp_id').value;
  const url = id ? 'fasilitas_publik/update.php' : 'fasilitas_publik/simpan.php';

  const fd = new FormData();
  if (id) fd.append('id', id);
  fd.append('nama',    nama);
  fd.append('jenis',   el('fp_jenis').value);
  fd.append('alamat',  el('fp_alamat').value.trim());
  fd.append('latitude', lat);
  fd.append('longitude', lng);
  fd.append('radius',  el('fp_radius').value);
  fd.append('kontak',  el('fp_kontak').value.trim());

  postData(url, fd).then(res => {
    if (res.status === 'success') {
      if (previewMarker) map.removeLayer(previewMarker);
      if (previewCircle) map.removeLayer(previewCircle);
      previewMarker = null; previewCircle = null;

      // Update data lokal dan bersihkan radius lama agar tidak double
      if (id) {
        const idx = fasilitasPublikList.findIndex(r => String(r.id) === String(id));
        if (idx >= 0) fasilitasPublikList[idx] = res.data;
        lgFasilitasPublik.clearLayers();
        const backup = [...fasilitasPublikList];
        fasilitasPublikList = []; // Reset state
        backup.forEach(item => renderFasilitasPublik(item));
      } else {
        renderFasilitasPublik(res.data);
      }

      refreshStatusPenduduk();
      hideModal('fasilitasPublikModal');
      showToast(id ? 'Fasilitas Publik diperbarui.' : 'Fasilitas Publik berhasil disimpan.');
    } else {
      showToast(res.message || 'Gagal menyimpan.', 'error');
    }
  });
});

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   SAVE: PENDUDUK MISKIN
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
el('btnSavePenduduk').addEventListener('click', () => {
  const nama = el('pm_nama').value.trim();
  const lat  = el('pm_latitude').value.trim();
  const lng  = el('pm_longitude').value.trim();

  if (!nama) { showToast('Nama penduduk wajib diisi.', 'error'); return; }
  if (!lat || !lng) { showToast('Klik pada peta untuk menentukan lokasi.', 'error'); return; }

  const cek = cekJangkauan(parseFloat(lat), parseFloat(lng));
  const id  = el('pm_id').value;
  const url = id ? 'penduduk_miskin/update.php' : 'penduduk_miskin/simpan.php';

  const fd = new FormData();
  if (id) fd.append('id', id);
  fd.append('nama',            nama);
  fd.append('nik',             el('pm_nik').value.trim());
  fd.append('keterangan',      el('pm_keterangan').value.trim());
  fd.append('latitude',        lat);
  fd.append('longitude',       lng);
  fd.append('status_jangkauan', cek.status);
  fd.append('fasilitas_publik_id', cek.id || '');

  postData(url, fd).then(res => {
    if (res.status === 'success') {
      if (previewMarker) { map.removeLayer(previewMarker); previewMarker = null; }

      // Update data lokal TANPA mereload halaman
      if (id) {
        const idx = pendudukList.findIndex(p => String(p.data.id) === String(id));
        if (idx >= 0) pendudukList[idx].data = res.data;
        refreshStatusPenduduk();
      } else {
        renderPenduduk(res.data);
        updateDashboardStats(); // <--- Tambahkan Baris Ini
      }
      
      hideModal('pendudukModal');
      showToast(id ? 'Data penduduk diperbarui.' : 'Penduduk miskin berhasil disimpan.');
    } else {
      showToast(res.message || 'Gagal menyimpan.', 'error');
    }
  });
});

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   GLOBAL: HAPUS DATA
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
window.hapusData = function (tipe, id, pesan) {
  showDeleteConfirm(pesan || 'Hapus data ini?', () => {
    const urlMap = {
      point:           'point/hapus.php',
      jalan:           'jalan/hapus.php',
      polygon:         'polygon/hapus.php',
      fasilitas_publik:    'fasilitas_publik/hapus.php',
      penduduk_miskin: 'penduduk_miskin/hapus.php',
    };

    const fd = new FormData();
    fd.append('id', id);

    postData(urlMap[tipe], fd).then(res => {
      if (res.status === 'success') {
        map.closePopup(); // Tutup popup di map
        showToast('Data berhasil dihapus.', 'success');

        // Hapus elemen dari Peta TANPA refresh web
        if (tipe === 'point') {
          const idx = APP_DATA.points.findIndex(x => String(x.id) === String(id));
          if (idx > -1) APP_DATA.points.splice(idx, 1);
          lgPoints.clearLayers();
          APP_DATA.points.forEach(renderPoint);
        } else if (tipe === 'jalan') {
          const idx = APP_DATA.jalan.findIndex(x => String(x.id) === String(id));
          if (idx > -1) APP_DATA.jalan.splice(idx, 1);
          lgJalan.clearLayers();
          APP_DATA.jalan.forEach(renderJalan);
        } else if (tipe === 'polygon') {
          const idx = APP_DATA.polygons.findIndex(x => String(x.id) === String(id));
          if (idx > -1) APP_DATA.polygons.splice(idx, 1);
          lgPolygon.clearLayers();
          APP_DATA.polygons.forEach(renderPolygon);
        } else if (tipe === 'fasilitas_publik') {
          fasilitasPublikList = fasilitasPublikList.filter(x => String(x.id) !== String(id));
          lgFasilitasPublik.clearLayers();
          const backup = [...fasilitasPublikList];
          fasilitasPublikList = [];
          backup.forEach(item => renderFasilitasPublik(item));
          refreshStatusPenduduk();
        } else if (tipe === 'penduduk_miskin') {
          pendudukList = pendudukList.filter(x => String(x.data.id) !== String(id));
          refreshStatusPenduduk();
        }

      } else {
        showToast(res.message || 'Gagal menghapus.', 'error');
      }
    });
  });
};

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   GLOBAL: EDIT Fasilitas Publik
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
window.editFasilitasPublik = function (id) {
  fetch(`api/get_fasilitas_publik.php?id=${id}`)
    .then(r => r.json())
    .then(res => {
      if (res.status !== 'success') { showToast('Data tidak ditemukan.', 'error'); return; }
      const d = res.data;
      el('fp_id').value       = d.id;
      el('fp_nama').value     = d.nama;
      el('fp_jenis').value    = d.jenis || 'Masjid';
      el('fp_alamat').value   = d.alamat || '';
      el('fp_kontak').value   = d.kontak || '';
      el('fp_latitude').value = d.latitude;
      el('fp_longitude').value= d.longitude;
      el('fp_radius').value   = d.radius;
      el('fp_radius_text').textContent = d.radius;
      el('fpModalTitle').textContent = 'Edit Fasilitas Publik';

      // Preview di peta
      if (previewMarker) map.removeLayer(previewMarker);
      if (previewCircle) map.removeLayer(previewCircle);
      const ll = L.latLng(parseFloat(d.latitude), parseFloat(d.longitude));
      previewMarker = L.marker(ll, { icon: createFPIcon() }).addTo(map);
      previewCircle = L.circle(ll, {
        radius: parseInt(d.radius),
        color: '#e53935', fillColor: '#ef9a9a', fillOpacity: 0.12,
        weight: 2, dashArray: '6 4'
      }).addTo(map);
      map.setView(ll, 16);

      map.closePopup();
      showModal('fasilitasPublikModal');
    })
    .catch(() => showToast('Gagal memuat data.', 'error'));
};

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   GLOBAL: EDIT PENDUDUK
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
window.editPenduduk = function (id) {
  fetch(`api/get_penduduk.php?id=${id}`)
    .then(r => r.json())
    .then(res => {
      if (res.status !== 'success') { showToast('Data tidak ditemukan.', 'error'); return; }
      const d = res.data;
      el('pm_id').value         = d.id;
      el('pm_nama').value       = d.nama;
      el('pm_nik').value        = d.nik || '';
      el('pm_keterangan').value = d.keterangan || '';
      el('pm_latitude').value   = d.latitude;
      el('pm_longitude').value  = d.longitude;
      el('pmModalTitle').textContent = 'Edit Penduduk Miskin';

      const cek = cekJangkauan(parseFloat(d.latitude), parseFloat(d.longitude));
      updateStatusJangkauan(cek);

      if (previewMarker) map.removeLayer(previewMarker);
      const ll = L.latLng(parseFloat(d.latitude), parseFloat(d.longitude));
      const warna = cek.status === 'Dalam Jangkauan' ? '#e53935' : '#2e7d32';
      previewMarker = L.circleMarker(ll, {
        radius: 8, color: warna, fillColor: warna, fillOpacity: 0.85, weight: 2
      }).addTo(map);
      map.setView(ll, 16);

      map.closePopup();
      showModal('pendudukModal');
    })
    .catch(() => showToast('Gagal memuat data.', 'error'));
};

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   UTILITY: POST DATA
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
function postData(url, formData) {
  return fetch(url, { method: 'POST', body: formData })
    .then(r => r.json())
    .catch(err => {
      console.error(err);
      showToast('Terjadi kesalahan koneksi.', 'error');
      return { status: 'error', message: 'Koneksi gagal.' };
    });
}

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   FITUR PENCARIAN (SEARCHING)
â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */
const searchInput = el('searchInput');
const searchResults = el('searchResults');

if (searchInput && searchResults) {
  searchInput.addEventListener('input', function() {
    const query = this.value.toLowerCase().trim();
    searchResults.innerHTML = '';
    
    // Minimal ketik 2 huruf baru mencari
    if (query.length < 2) {
      searchResults.classList.add('hidden');
      return;
    }

    let results = [];

    // 1. Cari Titik Biasa
    APP_DATA.points.forEach(item => {
      if (item.nama.toLowerCase().includes(query)) {
        results.push({ title: item.nama, type: 'ðŸ“ Titik Lokasi', lat: item.latitude, lng: item.longitude });
      }
    });

    // 2. Cari Fasilitas Publik
    fasilitasPublikList.forEach(item => {
      if (item.nama.toLowerCase().includes(query)) {
        results.push({ title: item.nama, type: `ðŸ•Œ Fasilitas Publik (${item.jenis})`, lat: item.latitude, lng: item.longitude });
      }
    });

    // 3. Cari Penduduk Miskin (Berdasarkan Nama atau NIK)
    pendudukList.forEach(p => {
      if (p.data.nama.toLowerCase().includes(query) || (p.data.nik && p.data.nik.includes(query))) {
        results.push({ title: p.data.nama, type: 'ðŸ‘¤ Penduduk Miskin', lat: p.data.latitude, lng: p.data.longitude });
      }
    });

    // 4. Cari Jalan
    APP_DATA.jalan.forEach(item => {
      if (item.nama_jalan.toLowerCase().includes(query)) {
        try {
          const feat = JSON.parse(item.koordinat);
          // Ambil titik koordinat pertama dari garis
          const coords = feat.geometry.coordinates[0]; 
          results.push({ title: item.nama_jalan, type: `ðŸ›£ï¸ Jalan (${item.status_jalan})`, lat: coords[1], lng: coords[0] });
        } catch(e) {}
      }
    });

    // 5. Cari Polygon
    APP_DATA.polygons.forEach(item => {
      if (item.nama_parsil.toLowerCase().includes(query)) {
        try {
          const feat = JSON.parse(item.koordinat);
          // Ambil titik koordinat pertama dari polygon
          const coords = feat.geometry.coordinates[0][0]; 
          results.push({ title: item.nama_parsil, type: `â¬  Polygon (${item.status_kepemilikan})`, lat: coords[1], lng: coords[0] });
        } catch(e) {}
      }
    });

    // Tampilkan Hasil
    if (results.length > 0) {
      results.forEach(res => {
        const div = document.createElement('div');
        div.className = 'search-item';
        div.innerHTML = `
          <span class="search-item-title">${res.title}</span>
          <span class="search-item-type">${res.type}</span>
        `;
        
        // Aksi saat item hasil dicentang
        div.addEventListener('click', () => {
          // Animasi terbang ke lokasi
          map.flyTo([parseFloat(res.lat), parseFloat(res.lng)], 18, { 
            animate: true, 
            duration: 1.5 
          });
          
          searchResults.classList.add('hidden');
          searchInput.value = res.title; // Isi kotak input dengan nama yang dipilih
          
          // Khusus tampilan HP: Sembunyikan sidebar agar peta terlihat langsung
          if (window.innerWidth <= 680) {
            el('sidebar').classList.remove('mobile-open');
          }
        });
        
        searchResults.appendChild(div);
      });
    } else {
      searchResults.innerHTML = '<div class="search-item-empty">Tidak ada data ditemukan</div>';
    }
    
    searchResults.classList.remove('hidden');
  });

  // Menyembunyikan dropdown jika klik di tempat lain
  document.addEventListener('click', (e) => {
    if (!searchInput.contains(e.target) && !searchResults.contains(e.target)) {
      searchResults.classList.add('hidden');
    }
  });
}

/* â”€â”€ Init â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
setMode('point');

})();


