'use client'

import { useEffect, useRef, useState } from 'react'

interface Props {
  lat: string
  lng: string
  onPick: (lat: number, lng: number) => void
}

const TILES = {
  map: {
    url: 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png',
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OSM</a> &copy; <a href="https://carto.com/">CARTO</a>',
    maxZoom: 19,
  },
  satellite: {
    url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
    attribution: '&copy; <a href="https://www.esri.com/">Esri</a>',
    maxZoom: 19,
  },
  satelliteLabels: {
    url: 'https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}',
    attribution: '',
    maxZoom: 19,
  },
}

const PIN_HTML = `<div style="width:22px;height:22px;border-radius:50% 50% 50% 0;background:#0096FF;border:3px solid #fff;box-shadow:0 2px 10px rgba(0,0,0,.4);transform:rotate(-45deg)"></div>`

export function LocationPicker({ lat, lng, onPick }: Props) {
  const containerRef = useRef<HTMLDivElement>(null)
  const mapRef = useRef<any>(null)
  const markerRef = useRef<any>(null)
  const LRef = useRef<any>(null)
  const tileLayerRef = useRef<any>(null)
  const labelLayerRef = useRef<any>(null)
  const skipSyncRef = useRef(false)
  const [isSatellite, setIsSatellite] = useState(false)

  useEffect(() => {
    if (!containerRef.current || mapRef.current) return

    const init = async () => {
      const L = (await import('leaflet')).default
      // @ts-ignore
      await import('leaflet/dist/leaflet.css')
      LRef.current = L

      const initLat = lat ? parseFloat(lat) : 39.3999
      const initLng = lng ? parseFloat(lng) : -8.2245
      const hasCoords = !!(lat && lng && !isNaN(initLat) && !isNaN(initLng))

      const map = L.map(containerRef.current!, {
        center: [initLat, initLng],
        zoom: hasCoords ? 13 : 7,
        zoomControl: true,
      })
      mapRef.current = map

      const t = TILES.map
      tileLayerRef.current = L.tileLayer(t.url, { attribution: t.attribution, maxZoom: t.maxZoom, subdomains: 'abcd' }).addTo(map)

      const makeIcon = () => L.divIcon({ className: '', html: PIN_HTML, iconSize: [22, 22], iconAnchor: [11, 22] })

      const placeMarker = (mlat: number, mlng: number) => {
        if (markerRef.current) {
          markerRef.current.setLatLng([mlat, mlng])
        } else {
          markerRef.current = L.marker([mlat, mlng], { icon: makeIcon(), draggable: true }).addTo(map)
          markerRef.current.on('dragend', () => {
            const pos = markerRef.current.getLatLng()
            skipSyncRef.current = true
            onPick(pos.lat, pos.lng)
          })
        }
      }

      if (hasCoords) placeMarker(initLat, initLng)

      map.on('click', (e: any) => {
        placeMarker(e.latlng.lat, e.latlng.lng)
        skipSyncRef.current = true
        onPick(e.latlng.lat, e.latlng.lng)
      })
    }

    init()

    return () => {
      if (mapRef.current) { mapRef.current.remove(); mapRef.current = null; markerRef.current = null; LRef.current = null; tileLayerRef.current = null; labelLayerRef.current = null }
    }
  }, []) // eslint-disable-line react-hooks/exhaustive-deps

  // Toggle satellite/map
  useEffect(() => {
    const map = mapRef.current
    const L = LRef.current
    if (!map || !L) return

    if (tileLayerRef.current) { map.removeLayer(tileLayerRef.current); tileLayerRef.current = null }
    if (labelLayerRef.current) { map.removeLayer(labelLayerRef.current); labelLayerRef.current = null }

    if (isSatellite) {
      const s = TILES.satellite
      tileLayerRef.current = L.tileLayer(s.url, { attribution: s.attribution, maxZoom: s.maxZoom }).addTo(map)
      const sl = TILES.satelliteLabels
      labelLayerRef.current = L.tileLayer(sl.url, { attribution: sl.attribution, maxZoom: sl.maxZoom, opacity: 0.9 }).addTo(map)
    } else {
      const t = TILES.map
      tileLayerRef.current = L.tileLayer(t.url, { attribution: t.attribution, maxZoom: t.maxZoom, subdomains: 'abcd' }).addTo(map)
    }

    if (markerRef.current) markerRef.current.bringToFront?.()
  }, [isSatellite])

  // Sync marker when user types lat/lng manually
  useEffect(() => {
    if (skipSyncRef.current) { skipSyncRef.current = false; return }
    const map = mapRef.current
    const L = LRef.current
    if (!map || !L || !lat || !lng) return
    const parsedLat = parseFloat(lat)
    const parsedLng = parseFloat(lng)
    if (isNaN(parsedLat) || isNaN(parsedLng)) return

    if (markerRef.current) {
      markerRef.current.setLatLng([parsedLat, parsedLng])
    } else {
      markerRef.current = L.marker([parsedLat, parsedLng], {
        icon: L.divIcon({ className: '', html: PIN_HTML, iconSize: [22, 22], iconAnchor: [11, 22] }),
        draggable: true,
      }).addTo(map)
      markerRef.current.on('dragend', () => {
        const pos = markerRef.current.getLatLng()
        skipSyncRef.current = true
        onPick(pos.lat, pos.lng)
      })
    }
    map.setView([parsedLat, parsedLng], Math.max(map.getZoom(), 13))
  }, [lat, lng]) // eslint-disable-line react-hooks/exhaustive-deps

  return (
    <div style={{ borderRadius: 10, overflow: 'hidden', border: '1.5px solid var(--ov-line)', marginBottom: 'var(--ov-space-3)', position: 'relative' }}>
      <div ref={containerRef} style={{ width: '100%', height: 480 }} aria-label="Mapa para seleccionar localização" />

      {/* Satellite toggle */}
      <button
        type="button"
        onClick={() => setIsSatellite((v) => !v)}
        style={{
          position: 'absolute', top: 10, right: 10, zIndex: 1000,
          padding: '5px 10px', borderRadius: 6,
          background: isSatellite ? '#0096FF' : 'rgba(255,255,255,0.92)',
          color: isSatellite ? '#fff' : '#0A1628',
          border: `1.5px solid ${isSatellite ? '#0096FF' : 'rgba(0,0,0,0.15)'}`,
          fontSize: 11, fontWeight: 600, fontFamily: 'var(--ov-font-sans)',
          cursor: 'pointer', backdropFilter: 'blur(4px)',
          boxShadow: '0 1px 4px rgba(0,0,0,.15)',
        }}
        aria-pressed={isSatellite}
      >
        {isSatellite ? 'Mapa' : 'Satélite'}
      </button>

      <div style={{ padding: '8px 12px', background: 'var(--ov-cloud)', borderTop: '1px solid var(--ov-line)', fontSize: 11, color: 'var(--ov-slate)', fontFamily: 'var(--ov-font-sans)' }}>
        Clica no mapa para marcar o spot · Arrasta o marcador para ajustar
      </div>
    </div>
  )
}
