import { useEffect, useRef, useState } from 'react'
import type { Map } from 'maplibre-gl'
import { useMapLibreMap } from '../maplibre/maplibreContext'
import { safeRemoveLayers } from '../maplibre/geoUtils'
import styles from './OverlayControls.module.css'

interface OverlayDef {
  id: string
  label: string
  tiles: string[]
  tileSize: 256 | 512
  opacity: number
}

const OVERLAYS: OverlayDef[] = [
  {
    id: 'streets',
    label: 'Streets',
    tiles: ['https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer/tile/{z}/{y}/{x}'],
    tileSize: 256,
    opacity: 0.75,
  },
  {
    id: 'labels',
    label: 'City names',
    tiles: ['https://a.basemaps.cartocdn.com/rastertiles/voyager_only_labels/{z}/{x}/{y}.png'],
    tileSize: 256,
    opacity: 1.0,
  },
  {
    id: 'borders',
    label: 'Borders',
    tiles: ['https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}'],
    tileSize: 256,
    opacity: 0.85,
  },
]

function addOverlay(map: Map, overlay: OverlayDef) {
  const srcId = `overlay-src-${overlay.id}`
  const lyrId = `overlay-lyr-${overlay.id}`
  map.addSource(srcId, { type: 'raster', tiles: overlay.tiles, tileSize: overlay.tileSize })
  map.addLayer({ id: lyrId, type: 'raster', source: srcId,
    paint: { 'raster-opacity': overlay.opacity } })
}

function removeOverlay(map: Map, overlay: OverlayDef) {
  safeRemoveLayers(map,
    [`overlay-lyr-${overlay.id}`],
    [`overlay-src-${overlay.id}`],
  )
}

export function OverlayControls() {
  const map = useMapLibreMap()
  const [active, setActive] = useState<Set<string>>(new Set())
  const activeRef = useRef(active)
  activeRef.current = active

  function toggle(overlay: OverlayDef) {
    setActive((prev) => {
      const next = new Set(prev)
      if (next.has(overlay.id)) {
        removeOverlay(map, overlay)
        next.delete(overlay.id)
      } else {
        addOverlay(map, overlay)
        next.add(overlay.id)
      }
      return next
    })
  }

  // Clean up all active overlays on unmount
  useEffect(() => {
    return () => {
      for (const id of activeRef.current) {
        const overlay = OVERLAYS.find(o => o.id === id)
        if (overlay) removeOverlay(map, overlay)
      }
    }
  }, [map])

  return (
    <div className={styles.group}>
      {OVERLAYS.map((o) => (
        <button
          key={o.id}
          className={`${styles.chip} ${active.has(o.id) ? styles.on : ''}`}
          onClick={() => toggle(o)}
          title={`Toggle ${o.label} overlay`}
        >
          {o.label}
        </button>
      ))}
    </div>
  )
}
