// public/js/app.js — SINERGI Core JavaScript v1.1
// Fix: Auto-zoom ke Kota Pontianak + auto-fitBounds setelah data dimuat

/* ============================================================
   KONSTANTA KOTA PONTIANAK
   ============================================================ */
const PONTIANAK = {
  lat:  -0.0263,
  lng:  109.3425,
  zoom: 13,
  // Bounding box seluruh Kota Pontianak (untuk fitBounds fallback)
  bounds: [[-0.115, 109.280], [0.055, 109.420]]
};

/* ============================================================
   UTILITY FUNCTIONS
   ============================================================ */
const App = {
  url: document.querySelector('meta[name="app-url"]')?.content || '',

  formatNumber(n) {
    return Number(n || 0).toLocaleString('id-ID');
  },

  formatRupiah(n) {
    return 'Rp ' + Number(n || 0).toLocaleString('id-ID');
  },

  formatTanggal(str) {
    if (!str) return '-';
    const bulan = ['','Januari','Februari','Maret','April','Mei','Juni',
      'Juli','Agustus','September','Oktober','November','Desember'];
    const d = new Date(str);
    return `${d.getDate()} ${bulan[d.getMonth() + 1]} ${d.getFullYear()}`;
  },

  async fetchJSON(url) {
    try {
      const r = await fetch(url);
      return await r.json();
    } catch (e) {
      console.error('Fetch error:', url, e);
      return null;
    }
  },

  showModal(id) {
    const el = document.getElementById(id);
    if (el) { el.classList.add('active'); document.body.style.overflow = 'hidden'; }
  },
  hideModal(id) {
    const el = document.getElementById(id);
    if (el) { el.classList.remove('active'); document.body.style.overflow = ''; }
  },

  confirmDelete(url, msg = 'Apakah Anda yakin ingin menghapus data ini?') {
    if (!confirm(msg)) return false;
    const form = document.createElement('form');
    form.method = 'POST';
    form.action = url;
    const csrf = document.querySelector('meta[name="csrf-token"]')?.content || '';
    form.innerHTML = `<input type="hidden" name="_token" value="${csrf}">`;
    document.body.appendChild(form);
    form.submit();
  },

  startClock() {
    const el = document.getElementById('live-clock');
    if (!el) return;
    const update = () => {
      const now = new Date();
      el.textContent = now.toLocaleTimeString('id-ID', {
        hour: '2-digit', minute: '2-digit', second: '2-digit'
      });
    };
    update();
    setInterval(update, 1000);
  },

  initFlash() {
    document.querySelectorAll('.flash-message').forEach(el => {
      setTimeout(() => {
        el.style.transition = 'opacity 0.5s, max-height 0.5s';
        el.style.opacity = '0';
        el.style.maxHeight = '0';
        el.style.overflow = 'hidden';
        setTimeout(() => el.remove(), 500);
      }, 4500);
    });
  },

  initTableSearch(inputId, tableId) {
    const input = document.getElementById(inputId);
    const table = document.getElementById(tableId);
    if (!input || !table) return;
    input.addEventListener('input', () => {
      const q = input.value.toLowerCase();
      table.querySelectorAll('tbody tr').forEach(row => {
        row.style.display = row.textContent.toLowerCase().includes(q) ? '' : 'none';
      });
    });
  },

  init() {
    this.startClock();
    this.initFlash();

    // Close modal on overlay click
    document.querySelectorAll('.modal-overlay').forEach(overlay => {
      overlay.addEventListener('click', e => {
        if (e.target === overlay) overlay.classList.remove('active');
      });
    });

    // Close modal on ESC
    document.addEventListener('keydown', e => {
      if (e.key === 'Escape') {
        document.querySelectorAll('.modal-overlay.active')
          .forEach(m => m.classList.remove('active'));
        document.body.style.overflow = '';
      }
    });

    // Sidebar active link highlight
    const path = window.location.pathname;
    document.querySelectorAll('.sidebar-nav a').forEach(a => {
      const href = a.getAttribute('href');
      if (href && href !== '/' && path.startsWith(href)) {
        a.classList.add('active');
      }
    });
  }
};

/* ============================================================
   GIS MAP MODULE — dengan auto-zoom ke Pontianak
   ============================================================ */
const GISMap = {
  map: null,
  layers: {},
  overlayLayers: {},
  heatLayer: null,
  _allMarkerBounds: [],   // Kumpulkan semua koordinat untuk fitBounds akhir

  warnaMiskin: {
    'Miskin Ekstrem': '#dc2626',
    'Miskin':         '#ea580c',
    'Rentan Miskin':  '#ca8a04',
  },

  createMarker(lat, lng, color, size = 10) {
    return L.circleMarker([lat, lng], {
      radius: size,
      fillColor: color,
      color: '#fff',
      weight: 2,
      opacity: 1,
      fillOpacity: 0.88
    });
  },

  createRIMarker(ri) {
    const icon = L.divIcon({
      className: '',
      html: `<div style="
        background:#16a34a;color:#fff;width:32px;height:32px;
        border-radius:50% 50% 50% 0;transform:rotate(-45deg);
        border:2.5px solid #fff;box-shadow:0 2px 8px rgba(0,0,0,0.35);
        display:flex;align-items:center;justify-content:center;font-size:14px;
      "><span style="transform:rotate(45deg)">⛪</span></div>`,
      iconSize: [32, 32],
      iconAnchor: [16, 32],
      popupAnchor: [0, -34]
    });
    return L.marker([parseFloat(ri.lat), parseFloat(ri.lng)], { icon });
  },

  // ─── INISIALISASI PETA ─────────────────────────────────────
  // Selalu mulai dari Kota Pontianak, zoom sesuai konteks
  init(containerId, lat, lng, zoom) {
    // Reset state untuk peta baru
    this._allMarkerBounds = [];

    // Gunakan koordinat Pontianak sebagai default yang kuat
    const centerLat  = (lat  && !isNaN(lat))  ? lat  : PONTIANAK.lat;
    const centerLng  = (lng  && !isNaN(lng))  ? lng  : PONTIANAK.lng;
    const initZoom   = (zoom && !isNaN(zoom)) ? zoom : PONTIANAK.zoom;

    this.map = L.map(containerId, {
      zoomControl: true,
      attributionControl: true,
      // Batasi pan agar tidak keluar wilayah Kalimantan Barat
      maxBounds: [[-2.0, 107.5], [2.0, 112.0]],
      maxBoundsViscosity: 0.8
    });

    // ── Langsung set view ke Pontianak dulu sebelum tile load ──
    this.map.setView([centerLat, centerLng], initZoom);

    // Tile layers
    const osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
      maxZoom: 19,
      // Tambahkan subdomains untuk load lebih cepat
      subdomains: ['a','b','c']
    });

    const satellite = L.tileLayer(
      'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
        attribution: 'Tiles © Esri',
        maxZoom: 19
      }
    );

    const topo = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
      attribution: '© OpenTopoMap',
      maxZoom: 17
    });

    osm.addTo(this.map);

    this.layers = {
      '🗺 Peta Jalan': osm,
      '🛰 Satelit': satellite,
      '🏔 Topografi': topo
    };

    // Layer control dasar
    this._layerControl = L.control.layers(this.layers, {}, {
      position: 'topright',
      collapsed: true
    }).addTo(this.map);

    // Tombol reset zoom ke Pontianak
    this._addResetButton();

    return this.map;
  },

  // Tombol reset zoom ke seluruh Kota Pontianak
  _addResetButton() {
    const ResetControl = L.Control.extend({
      options: { position: 'topleft' },
      onAdd: () => {
        const btn = L.DomUtil.create('button', '');
        btn.innerHTML = '🏙';
        btn.title = 'Kembali ke Kota Pontianak';
        btn.style.cssText = `
          width:30px;height:30px;border:2px solid rgba(0,0,0,0.2);
          border-radius:4px;background:#fff;cursor:pointer;
          font-size:14px;display:flex;align-items:center;
          justify-content:center;box-shadow:0 1px 5px rgba(0,0,0,0.2);
        `;
        L.DomEvent.on(btn, 'click', L.DomEvent.stopPropagation)
          .on(btn, 'click', L.DomEvent.preventDefault)
          .on(btn, 'click', () => {
            this.map.flyToBounds(PONTIANAK.bounds, {
              duration: 0.8,
              padding: [20, 20]
            });
          });
        return btn;
      }
    });
    new ResetControl().addTo(this.map);
  },

  // ─── LAYER WARGA MISKIN ────────────────────────────────────
  addWargaLayer(wargaData, onClickCb) {
    const group = L.featureGroup();   // featureGroup mendukung getBounds()
    wargaData.forEach(w => {
      if (!w.lat || !w.lng) return;
      const lat = parseFloat(w.lat);
      const lng = parseFloat(w.lng);
      if (isNaN(lat) || isNaN(lng)) return;

      const color = w.is_blind_spot
        ? '#7c3aed'
        : (this.warnaMiskin[w.status_kemiskinan] || '#6b7280');
      const size  = w.status_kemiskinan === 'Miskin Ekstrem' ? 11 : 9;

      const m = this.createMarker(lat, lng, color, size);

      const popup = `
        <div style="min-width:200px;font-family:Inter,system-ui,sans-serif">
          <strong style="font-size:13px">${w.nama || 'Data laporan'}</strong><br>
          <span style="font-size:11px;color:#6b7280">${w.kelurahan || ''}</span><br>
          <span style="display:inline-block;margin-top:5px;padding:2px 9px;border-radius:10px;
            font-size:11px;font-weight:700;background:${color}22;color:${color}">
            ${w.status_kemiskinan || ''}
          </span>
          ${w.level_prioritas ? `<br><span style="font-size:11px;margin-top:3px;display:block">
            Prioritas: <strong>${w.level_prioritas}</strong>
            ${w.skor_prioritas ? `(${w.skor_prioritas}/100)` : ''}</span>` : ''}
          ${w.penghasilan_bulanan !== undefined ? `<span style="font-size:11px;color:#6b7280">
            Penghasilan: Rp ${Number(w.penghasilan_bulanan||0).toLocaleString('id-ID')}/bln</span>` : ''}
          ${w.is_blind_spot ? '<br><span style="color:#7c3aed;font-weight:700;font-size:11px;display:block;margin-top:3px">⚠ Blind Spot — Belum terjangkau RI</span>' : ''}
        </div>`;

      m.bindPopup(popup, { maxWidth: 240 });
      if (onClickCb) m.on('click', () => onClickCb(w));
      group.addLayer(m);
      this._allMarkerBounds.push([lat, lng]);
    });
    group.addTo(this.map);
    return group;
  },

  // ─── LAYER RUMAH IBADAH ────────────────────────────────────
  addRILayer(riData, onClickCb) {
    const group = L.featureGroup();
    riData.forEach(ri => {
      if (!ri.lat || !ri.lng) return;
      const lat = parseFloat(ri.lat);
      const lng = parseFloat(ri.lng);
      if (isNaN(lat) || isNaN(lng)) return;

      const m = this.createRIMarker(ri);

      // Radius lingkaran pelayanan
      const radius = parseInt(ri.radius_meter) || 500;
      const circle = L.circle([lat, lng], {
        radius,
        fillColor: '#16a34a',
        fillOpacity: 0.07,
        color: '#16a34a',
        weight: 1.5,
        dashArray: '6,5',
        interactive: false
      });

      const popup = `
        <div style="min-width:200px;font-family:Inter,system-ui,sans-serif">
          <strong style="font-size:13px">⛪ ${ri.nama}</strong><br>
          <span style="font-size:11px;color:#6b7280">${ri.jenis || ''} • ${ri.kelurahan || ''}</span>
          ${ri.alamat ? `<br><span style="font-size:11px;color:#374151">${ri.alamat}</span>` : ''}
          <br><span style="font-size:11px;color:#16a34a;font-weight:600;display:block;margin-top:4px">
            📏 Radius pelayanan: ${radius.toLocaleString()}m</span>
          ${ri.nama_ketua ? `<span style="font-size:11px;color:#6b7280">Ketua: ${ri.nama_ketua}</span>` : ''}
        </div>`;

      m.bindPopup(popup, { maxWidth: 240 });
      if (onClickCb) m.on('click', () => onClickCb(ri));

      group.addLayer(circle);
      group.addLayer(m);
      this._allMarkerBounds.push([lat, lng]);
    });
    group.addTo(this.map);
    return group;
  },

  // ─── LAYER LAPORAN PUBLIK ──────────────────────────────────
  addLaporanLayer(laporanData) {
    const group = L.featureGroup();
    laporanData.forEach(lap => {
      if (!lap.lat || !lap.lng) return;
      const lat = parseFloat(lap.lat);
      const lng = parseFloat(lap.lng);
      if (isNaN(lat) || isNaN(lng)) return;

      const m = this.createMarker(lat, lng, '#0284c7', 8);
      m.bindPopup(`
        <div style="min-width:180px;font-family:Inter,system-ui,sans-serif">
          <strong style="font-size:13px">📋 Laporan Masuk</strong><br>
          <span style="font-size:12px">${lap.nama_warga || ''}</span><br>
          <code style="font-size:10px;background:#f1f5f9;padding:1px 5px;border-radius:3px">
            ${lap.kode_laporan || ''}</code>
        </div>`, { maxWidth: 200 });
      group.addLayer(m);
      this._allMarkerBounds.push([lat, lng]);
    });
    group.addTo(this.map);
    return group;
  },

  // ─── HEATMAP LAYER ─────────────────────────────────────────
  addHeatmap(points) {
    if (typeof L.heatLayer === 'undefined') {
      console.warn('Leaflet.heat tidak tersedia');
      return;
    }
    const data = points
      .map(p => [parseFloat(p.lat), parseFloat(p.lng), parseFloat(p.intensity || 0.5)])
      .filter(p => !isNaN(p[0]) && !isNaN(p[1]) && p[0] !== 0);

    if (this.heatLayer) this.map.removeLayer(this.heatLayer);
    this.heatLayer = L.heatLayer(data, {
      radius: 28,
      blur: 22,
      maxZoom: 16,
      max: 1.0,
      gradient: {
        0.0: 'transparent',
        0.3: '#fef9c3',
        0.55: '#fb923c',
        0.75: '#ef4444',
        1.0: '#7f1d1d'
      }
    }).addTo(this.map);
  },

  // ─── AUTO FIT BOUNDS ───────────────────────────────────────
  // Panggil ini SETELAH semua layer dimuat untuk zoom ke data
  autoFitBounds(forceKotaPontianak = false) {
    if (forceKotaPontianak || this._allMarkerBounds.length === 0) {
      // Tidak ada data → tampilkan seluruh Kota Pontianak
      this.map.flyToBounds(PONTIANAK.bounds, {
        duration: 0.6,
        padding: [20, 20],
        maxZoom: 14
      });
      return;
    }

    try {
      const bounds = L.latLngBounds(this._allMarkerBounds);
      if (bounds.isValid()) {
        // Jika data sangat menyebar → fit ke batas data
        // Jika data sangat mepet (1-2 titik) → zoom level wajar
        const boundsSize = bounds.getNorthEast().distanceTo(bounds.getSouthWest());
        if (boundsSize < 500) {
          // Data terlalu dekat → zoom ke tengah dengan zoom 15
          this.map.flyTo(bounds.getCenter(), 15, { duration: 0.6 });
        } else {
          this.map.flyToBounds(bounds, {
            duration: 0.6,
            padding: [40, 40],
            maxZoom: 15   // Jangan zoom terlalu dekat
          });
        }
      } else {
        this.map.flyToBounds(PONTIANAK.bounds, { duration: 0.5 });
      }
    } catch (e) {
      this.map.flyToBounds(PONTIANAK.bounds, { duration: 0.5 });
    }
  },

  // fitBounds dari layerGroup (kompatibel dengan kode lama)
  fitBounds(layerGroup) {
    try {
      const bounds = layerGroup.getBounds();
      if (bounds.isValid()) {
        this.map.flyToBounds(bounds, { duration: 0.5, padding: [30, 30] });
      }
    } catch (e) {
      this.autoFitBounds(true);
    }
  }
};

/* ============================================================
   CHART MODULE (Chart.js wrapper)
   ============================================================ */
const Charts = {
  defaults: {
    fontFamily: "'Inter', system-ui, sans-serif",
    colors: ['#1a3a5c', '#e8a020', '#16a34a', '#dc2626', '#0284c7', '#7c3aed', '#ea580c', '#0d9488']
  },

  bar(canvasId, labels, datasets, opts = {}) {
    const ctx = document.getElementById(canvasId);
    if (!ctx) return null;
    return new Chart(ctx, {
      type: 'bar',
      data: {
        labels,
        datasets: datasets.map((d, i) => ({
          backgroundColor: this.defaults.colors[i % this.defaults.colors.length] + 'cc',
          borderColor:     this.defaults.colors[i % this.defaults.colors.length],
          borderRadius: 4,
          borderWidth: 1,
          ...d
        }))
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: { display: datasets.length > 1 },
          tooltip: { callbacks: { label: ctx => ' ' + Number(ctx.raw).toLocaleString('id-ID') } }
        },
        scales: {
          y: { beginAtZero: true, grid: { color: '#f1f5f9' }, ticks: { font: { size: 11 } } },
          x: { grid: { display: false }, ticks: { font: { size: 11 } } }
        },
        ...opts
      }
    });
  },

  line(canvasId, labels, datasets, opts = {}) {
    const ctx = document.getElementById(canvasId);
    if (!ctx) return null;
    return new Chart(ctx, {
      type: 'line',
      data: {
        labels,
        datasets: datasets.map((d, i) => ({
          borderColor:     this.defaults.colors[i % this.defaults.colors.length],
          backgroundColor: this.defaults.colors[i % this.defaults.colors.length] + '18',
          tension: 0.4, fill: true, borderWidth: 2.5,
          pointRadius: 4, pointHoverRadius: 6,
          ...d
        }))
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: { legend: { display: datasets.length > 1 } },
        scales: {
          y: { beginAtZero: true, grid: { color: '#f1f5f9' }, ticks: { font: { size: 11 } } },
          x: { grid: { display: false }, ticks: { font: { size: 11 } } }
        },
        ...opts
      }
    });
  },

  donut(canvasId, labels, data, colors) {
    const ctx = document.getElementById(canvasId);
    if (!ctx) return null;
    return new Chart(ctx, {
      type: 'doughnut',
      data: {
        labels,
        datasets: [{
          data,
          backgroundColor: colors || this.defaults.colors,
          borderWidth: 2,
          borderColor: '#fff'
        }]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: {
            position: 'right',
            labels: { font: { size: 11 }, padding: 14, usePointStyle: true }
          }
        },
        cutout: '65%'
      }
    });
  }
};

/* ============================================================
   LOCATION PICKER — untuk form laporan & input warga
   ============================================================ */
const LocationPicker = {
  map: null,
  marker: null,

  init(mapId, latInputId, lngInputId, initLat, initLng) {
    // Selalu mulai dari Pontianak
    const startLat = (initLat && !isNaN(initLat)) ? initLat : PONTIANAK.lat;
    const startLng = (initLng && !isNaN(initLng)) ? initLng : PONTIANAK.lng;

    this.map = L.map(mapId, { zoomControl: true }).setView([startLat, startLng], 14);

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap',
      maxZoom: 19,
      subdomains: ['a','b','c']
    }).addTo(this.map);

    // Jika ada koordinat awal, langsung pasang marker
    if (initLat && initLng && !isNaN(initLat)) {
      this.placeMarker(initLat, initLng, latInputId, lngInputId);
    }

    // Klik peta = pasang / pindah marker
    this.map.on('click', e => {
      this.placeMarker(e.latlng.lat, e.latlng.lng, latInputId, lngInputId);
    });

    // Kontrol tombol lokasi saya
    this._addGeolocateButton(latInputId, lngInputId);

    // Instruksi klik
    const hint = L.control({ position: 'bottomleft' });
    hint.onAdd = () => {
      const d = L.DomUtil.create('div');
      d.style.cssText = 'background:rgba(255,255,255,0.9);padding:6px 10px;border-radius:6px;font-size:11px;color:#374151;box-shadow:0 1px 4px rgba(0,0,0,0.15)';
      d.innerHTML = '📍 Klik peta atau drag marker untuk menentukan lokasi';
      return d;
    };
    hint.addTo(this.map);
  },

  placeMarker(lat, lng, latInputId, lngInputId) {
    if (this.marker) this.map.removeLayer(this.marker);
    this.marker = L.marker([lat, lng], {
      draggable: true,
      autoPan: true
    }).addTo(this.map);
    this.marker.bindPopup('📍 Lokasi dipilih').openPopup();

    document.getElementById(latInputId).value = lat.toFixed(7);
    document.getElementById(lngInputId).value = lng.toFixed(7);

    this.marker.on('dragend', e => {
      const pos = e.target.getLatLng();
      document.getElementById(latInputId).value = pos.lat.toFixed(7);
      document.getElementById(lngInputId).value = pos.lng.toFixed(7);
    });
  },

  _addGeolocateButton(latInputId, lngInputId) {
    const GeoBtn = L.Control.extend({
      options: { position: 'topright' },
      onAdd: () => {
        const btn = L.DomUtil.create('button', '');
        btn.innerHTML = '📍 Lokasi Saya';
        btn.title = 'Gunakan lokasi GPS saya';
        btn.style.cssText = `
          padding:6px 10px;border:2px solid rgba(0,0,0,0.2);border-radius:4px;
          background:#1a3a5c;color:#fff;cursor:pointer;font-size:11px;font-weight:600;
          box-shadow:0 1px 5px rgba(0,0,0,0.2);white-space:nowrap;
        `;
        L.DomEvent.disableClickPropagation(btn);
        btn.onclick = () => {
          if (!navigator.geolocation) {
            alert('GPS tidak tersedia di browser Anda');
            return;
          }
          btn.innerHTML = '⌛ Mencari...';
          btn.disabled = true;
          navigator.geolocation.getCurrentPosition(
            pos => {
              const { latitude, longitude } = pos.coords;
              this.placeMarker(latitude, longitude, latInputId, lngInputId);
              this.map.flyTo([latitude, longitude], 17, { duration: 0.8 });
              btn.innerHTML = '📍 Lokasi Saya';
              btn.disabled = false;
            },
            err => {
              alert('Gagal mendapatkan lokasi: ' + err.message);
              btn.innerHTML = '📍 Lokasi Saya';
              btn.disabled = false;
            },
            { enableHighAccuracy: true, timeout: 10000 }
          );
        };
        return btn;
      }
    });
    new GeoBtn().addTo(this.map);
  }
};

// ── Bootstrap ──
document.addEventListener('DOMContentLoaded', () => App.init());
