<template>
  <div ref="containerRef" class="gw-map" />
</template>

<script setup lang="ts">
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import 'leaflet.markercluster';
import 'leaflet.markercluster/dist/MarkerCluster.css';
import 'leaflet.markercluster/dist/MarkerCluster.Default.css';
import '@geoman-io/leaflet-geoman-free';
import '@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css';
import type { GeoMember } from '~/composables/useCesiumProfiles';

type LoadPolygon = { coords: [number, number][]; name: string } | null;

const props = defineProps<{
  members: GeoMember[];
  clearTrigger?: number;
  loadPolygon?: LoadPolygon;
}>();

const emit = defineEmits<{
  polygonChange: [polygon: [number, number][] | null, name?: string];
}>();

const containerRef = ref<HTMLDivElement | null>(null);
let map: L.Map | null = null;
let cluster: any = null;
let polygonLayer: L.Layer | null = null;

onMounted(() => {
  if (!containerRef.value) return;

  map = L.map(containerRef.value).setView([46.5, 2.5], 6);
  L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
  }).addTo(map);

  cluster = (L as any).markerClusterGroup();
  map.addLayer(cluster);

  // Geoman controls
  if (map.pm) {
    map.pm.addControls({
      position: 'topleft',
      drawCircle: false,
      drawCircleMarker: false,
      drawMarker: false,
      drawPolyline: false,
      drawText: false,
      editMode: false,
      dragMode: false,
      cutPolygon: false,
      rotateMode: false,
      removalMode: false,
    });
    map.pm.setLang('fr');
  }

  map.on('pm:create', (e: any) => {
    if (polygonLayer) {
      map!.removeLayer(polygonLayer);
    }
    polygonLayer = e.layer;
    const latlngs = (e.layer as L.Polygon).getLatLngs()[0] as L.LatLng[];
    emit('polygonChange', latlngs.map((ll) => [ll.lat, ll.lng]));
  });

  map.on('pm:remove', () => {
    polygonLayer = null;
    emit('polygonChange', null);
  });

  // Populate initial markers
  updateMarkers(props.members);
});

onUnmounted(() => {
  if (map) {
    map.remove();
    map = null;
    cluster = null;
  }
});

// Clear polygon when clearTrigger changes
watch(() => props.clearTrigger, () => {
  if (!props.clearTrigger || !map) return;
  if (polygonLayer) {
    const center = map.getCenter();
    const zoom = map.getZoom();
    map.removeLayer(polygonLayer);
    polygonLayer = null;
    map.setView(center, zoom, { animate: false });
  }
  if (map.pm) {
    map.pm.disableDraw();
  }
});

// Load a saved polygon
watch(() => props.loadPolygon, (loadPolygon) => {
  if (!map || !loadPolygon) return;

  if (polygonLayer) {
    map.removeLayer(polygonLayer);
    polygonLayer = null;
  }

  const latlngs = loadPolygon.coords.map(([lat, lng]) => L.latLng(lat, lng));
  const poly = L.polygon(latlngs, { color: '#3388ff' }).addTo(map);
  polygonLayer = poly;
  map.fitBounds(poly.getBounds(), { padding: [20, 20] });
  emit('polygonChange', loadPolygon.coords, loadPolygon.name);
});

// Update markers when members change
function updateMarkers(members: GeoMember[]) {
  if (!cluster) return;
  cluster.clearLayers();
  const markers = members.map((m) =>
    L.circleMarker([m.lat, m.lon], {
      radius: 6,
      color: '#f59e0b',
      fillColor: '#f59e0b',
      fillOpacity: 0.7,
    }).bindPopup(
      `<strong>${m.title || m.pubkey.slice(0, 8)}</strong>${m.city ? '<br>' + m.city : ''}`
    )
  );
  cluster.addLayers(markers);
}

watch(() => props.members, (members) => {
  updateMarkers(members);
});
</script>

<style scoped>
.gw-map {
  height: 500px;
  width: 100%;
  border-radius: 0.75rem;
}
</style>
