import React, { useEffect, useRef, useState } from 'react';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import { getAppUrl } from '../../utils/url';

type LayerType = 'kabupaten' | 'kecamatan' | 'kelurahan';

const LAYER_CONFIGS = {
  kabupaten: { url: '/admin_kab.json', label: 'Kabupaten', style: { color: '#001178', weight: 3, fillColor: '#0028B3', fillOpacity: 0.12 } },
  kecamatan: { url: '/admin_kec.json', label: 'Kecamatan', style: { color: '#ffffff', weight: 1.5, fillColor: '#0028B3', fillOpacity: 0.3 } },
  kelurahan: { url: '/admin_kel.json', label: 'Kelurahan/Desa', style: { color: '#ffffff', weight: 1, fillColor: '#0028B3', fillOpacity: 0.4 } },
};

const TILES = {
  default: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png',
  streets: 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png',
  satellite: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
};

const PIN = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 56 68" width="36" height="44">
  <path d="M28 2C16.4 2 7 11.4 7 23 7 38.5 28 66 28 66S49 38.5 49 23C49 11.4 39.6 2 28 2Z" fill="#E53935"/>
  <circle cx="28" cy="23" r="12" fill="white"/>
  <circle cx="28" cy="23" r="6" fill="#E53935"/>
</svg>`;

export default function BogorMap() {
  const containerRef = useRef<HTMLDivElement>(null);
  const [mapInstance, setMapInstance] = useState<L.Map | null>(null);
  const tileLayer = useRef<L.TileLayer | null>(null);
  const geoLayer = useRef<L.GeoJSON | null>(null);
  const markerGroup = useRef<L.LayerGroup | null>(null);
  const cache = useRef<Record<string, any>>({});

  const [activeLayer, setActiveLayer] = useState<LayerType>('kabupaten');
  const [basemap, setBasemap] = useState<keyof typeof TILES>('default');
  const [showDinas, setShowDinas] = useState(true);
  const [loading, setLoading] = useState(false);
  const [selectedDinas, setSelectedDinas] = useState<any>(null);

  // ── EFFECT 1: Init map (runs once on mount) ─────────────────────────────
  useEffect(() => {
    if (!containerRef.current || mapInstance) return;

    const m = L.map(containerRef.current, {
      center: [-6.4831, 106.8288],
      zoom: 10,
      zoomControl: false,
    });
    L.control.zoom({ position: 'bottomright' }).addTo(m);

    tileLayer.current = L.tileLayer(TILES.default, { subdomains: 'abcd', maxZoom: 20 }).addTo(m);
    markerGroup.current = L.layerGroup().addTo(m);
    setMapInstance(m);

    return () => { m.remove(); setMapInstance(null); };
  }, []);

  // ── EFFECT 2: GeoJSON batas wilayah ────────────────────────────────────
  useEffect(() => {
    if (!mapInstance) return;
    const m = mapInstance;
    const cfg = LAYER_CONFIGS[activeLayer];

    const render = (data: any) => {
      if (geoLayer.current) { m.removeLayer(geoLayer.current); }

      geoLayer.current = L.geoJSON(data, {
        style: () => cfg.style as L.PathOptions,
        onEachFeature: (feature, layer) => {
          const p = feature.properties || {};
          const name =
            activeLayer === 'kabupaten' ? p.NKAB :
              activeLayer === 'kecamatan' ? p.NKEC :
                p.NKEL ? `${p.NKEL} (Kec. ${p.NKEC || ''})` : '';

          (layer as L.Path).on({
            mouseover(e) {
              (e.target as L.Path).setStyle({ fillColor: '#e8741c', fillOpacity: activeLayer === 'kabupaten' ? 0.35 : 0.75 });
              (e.target as L.Path).bindTooltip(
                `<b style="font-size:12px;color:#1e2a3a;">${String(name).toLowerCase()}</b>`,
                { sticky: true, className: 'bmap-tip' }
              ).openTooltip((e as L.LeafletMouseEvent).latlng);
            },
            mouseout(e) {
              geoLayer.current?.resetStyle(e.target);
              (e.target as L.Path).closeTooltip();
            },
            click() {
              m.fitBounds((layer as L.Polygon).getBounds(), { padding: [40, 40] });
            },
          });
        },
      }).addTo(m);

      if (markerGroup.current) markerGroup.current.bringToFront();
      try { const b = geoLayer.current.getBounds(); if (b.isValid()) m.fitBounds(b, { padding: [20, 20] }); } catch (_) { }
      setLoading(false);
    };

    if (cache.current[activeLayer]) { render(cache.current[activeLayer]); return; }

    setLoading(true);
    fetch(getAppUrl(cfg.url))
      .then(r => { if (!r.ok) throw new Error(`HTTP ${r.status}`); return r.json(); })
      .then(d => { cache.current[activeLayer] = d; render(d); })
      .catch(e => { console.error('GeoJSON load error:', e); setLoading(false); });
  }, [mapInstance, activeLayer]);

  // ── EFFECT 3: Basemap switch ────────────────────────────────────────────
  useEffect(() => {
    if (!mapInstance || !tileLayer.current) return;
    mapInstance.removeLayer(tileLayer.current);
    tileLayer.current = L.tileLayer(TILES[basemap], { subdomains: 'abcd', maxZoom: 20 }).addTo(mapInstance);
    tileLayer.current.bringToBack();
  }, [mapInstance, basemap]);

  // ── EFFECT 4: Dinas markers ─────────────────────────────────────────────
  useEffect(() => {
    if (!mapInstance || !markerGroup.current) return;
    const m = mapInstance;
    const g = markerGroup.current;
    g.clearLayers();
    if (!showDinas) return;

    fetch(getAppUrl('/api/dinas'))
      .then(r => r.json())
      .then(res => {
        const pts: any[] = res.data || [];
        const icon = L.divIcon({
          className: '',
          html: `<div style="filter:drop-shadow(0 4px 8px rgba(0,0,0,0.3));cursor:pointer;transition:transform .2s;"><img src="${getAppUrl('/image/titik.svg')}" style="width:36px;height:36px;" /></div>`,
          iconSize:    [36, 36],
          iconAnchor:  [18, 33],
          popupAnchor: [0, -35],
        });

        pts.forEach(pt => {
          if (!pt.latitude || !pt.longitude) return;
          L.marker([pt.latitude, pt.longitude], { icon })
            .bindTooltip(`<b style="font-size:12px;">${pt.nama}</b>`, { direction: 'top', offset: [0, -35], className: 'bmap-tip' })
            .on('click', () => { setSelectedDinas(pt); m.flyTo([pt.latitude, pt.longitude], 15, { duration: 1.5 }); })
            .addTo(g);
        });
      })
      .catch(e => console.error('Dinas load error:', e));
  }, [mapInstance, showDinas]);

  // ── JSX ─────────────────────────────────────────────────────────────────
  return (
    <div style={{ position: 'relative', width: '100%', height: '500px', borderRadius: '14px', overflow: 'hidden', border: '1px solid #E2E8F0' }}>

      {/* Basemap buttons */}
      <div style={{ position: 'absolute', top: '12px', right: '12px', zIndex: 999, display: 'flex', background: '#fff', padding: '4px', borderRadius: '10px', boxShadow: '0 4px 12px rgba(0,0,0,0.12)', gap: '2px' }}>
        {(['default', 'streets', 'satellite'] as const).map(k => (
          <button key={k} onClick={() => setBasemap(k)} style={{ border: 'none', background: basemap === k ? '#0028B3' : 'transparent', color: basemap === k ? '#fff' : '#475569', padding: '6px 13px', fontSize: '12px', fontWeight: 600, borderRadius: '7px', cursor: 'pointer', transition: 'all .18s' }}>
            {k === 'default' ? 'Default' : k === 'streets' ? 'Jalan' : 'Satelit'}
          </button>
        ))}
      </div>

      {/* Loading */}
      {loading && (
        <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: '10px', background: 'rgba(255,255,255,0.8)', zIndex: 1000 }}>
          <div style={{ width: '30px', height: '30px', border: '3px solid #E2E8F0', borderTopColor: '#0028B3', borderRadius: '50%', animation: 'bspin .8s linear infinite' }} />
          <span style={{ fontSize: '12px', color: '#0028B3', fontWeight: 600 }}>Memuat batas wilayah…</span>
          <style>{`@keyframes bspin{to{transform:rotate(360deg)}}`}</style>
        </div>
      )}

      {/* Layer & instansi buttons */}
      <div style={{ position: 'absolute', top: '12px', left: '12px', zIndex: 999, display: 'flex', alignItems: 'center', background: '#fff', padding: '4px', borderRadius: '10px', boxShadow: '0 4px 12px rgba(0,0,0,0.12)', gap: '2px' }}>
        {(Object.keys(LAYER_CONFIGS) as LayerType[]).map(k => (
          <button key={k} onClick={() => setActiveLayer(k)} style={{ border: 'none', background: activeLayer === k ? '#0028B3' : 'transparent', color: activeLayer === k ? '#fff' : '#475569', padding: '6px 13px', fontSize: '12px', fontWeight: 600, borderRadius: '7px', cursor: 'pointer', transition: 'all .18s' }}>
            {LAYER_CONFIGS[k].label}
          </button>
        ))}
        <div style={{ width: '1px', height: '18px', background: '#E2E8F0', margin: '0 2px' }} />
        <button onClick={() => setShowDinas(v => !v)} style={{ border: 'none', background: showDinas ? '#e8741c' : 'transparent', color: showDinas ? '#fff' : '#475569', padding: '6px 13px', fontSize: '12px', fontWeight: 600, borderRadius: '7px', cursor: 'pointer', transition: 'all .18s', display: 'flex', alignItems: 'center', gap: '5px' }}>
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" style={{ width: '12px', height: '12px' }}>
            <circle cx="12" cy="10" r="3" /><path d="M12 21.7C17.3 17 20 13 20 10a8 8 0 1 0-16 0c0 3 2.7 7 8 11.7z" />
          </svg>
          Kantor Instansi
        </button>
      </div>

      {/* Selected dinas card */}
      {selectedDinas && (
        <div style={{ position: 'absolute', bottom: '14px', left: '14px', maxWidth: '320px', background: '#fff', borderRadius: '12px', boxShadow: '0 8px 24px rgba(0,0,0,0.13)', border: '1px solid #E2E8F0', padding: '12px 14px', zIndex: 999, display: 'flex', flexDirection: 'column', gap: '6px' }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <span style={{ background: '#FEF3C7', color: '#D97706', fontSize: '10px', fontWeight: 700, padding: '2px 8px', borderRadius: '4px', textTransform: 'uppercase' }}>{selectedDinas.singkatan || 'KANTOR'}</span>
            <button onClick={() => setSelectedDinas(null)} style={{ background: 'none', border: 'none', color: '#94A3B8', cursor: 'pointer', fontSize: '18px', padding: '0 2px' }}>×</button>
          </div>
          <h4 style={{ margin: 0, fontSize: '13px', fontWeight: 700, color: '#1e2a3a', lineHeight: 1.4 }}>{selectedDinas.nama}</h4>
          <span style={{ fontSize: '11px', color: '#64748B' }}>Kompleks Pemda Cibinong</span>
        </div>
      )}

      {/* Map container – must NOT have overflow:hidden on parent for Leaflet to size correctly */}
      <div ref={containerRef} style={{ width: '100%', height: '100%', zIndex: 1 }} />

      <style>{`
        .bmap-tip {
          background: rgba(255,255,255,0.95) !important;
          border: 1px solid #e2e8f0 !important;
          border-radius: 6px !important;
          box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important;
          padding: 4px 8px !important;
          font-family: inherit !important;
          pointer-events: none !important;
        }
        .bmap-tip::before { display:none !important; }
        .leaflet-marker-icon, .leaflet-marker-shadow { background:transparent !important; border:none !important; }
      `}</style>
    </div>
  );
}
