import React, { useCallback, useEffect, useMemo, useRef } from 'react'

function hashHtml(value) {
  let hash = 0
  const step = Math.max(1, Math.floor(value.length / 64))
  for (let i = 0; i < value.length; i += step) {
    hash = ((hash << 5) - hash) + value.charCodeAt(i)
    hash |= 0
  }
  return `${value.length}-${Math.abs(hash)}`
}

export default function MapFrame({ html }) {
  const iframeRef = useRef(null)
  const timersRef = useRef([])
  const frameKey = useMemo(() => hashHtml(html || ''), [html])

  const clearTimers = useCallback(() => {
    timersRef.current.forEach((id) => window.clearTimeout(id))
    timersRef.current = []
  }, [])

  const recenterFromLayers = useCallback(() => {
    const iframe = iframeRef.current
    if (!iframe) return

    try {
      const win = iframe.contentWindow
      const doc = iframe.contentDocument || win?.document
      if (!win || !doc || !win.L) return

      const maps = Object.values(win).filter(
        (item) => item
          && typeof item.fitBounds === 'function'
          && typeof item.eachLayer === 'function'
          && typeof item.invalidateSize === 'function',
      )

      const map = maps[0]
      if (!map) return

      map.invalidateSize(true)
      const bounds = win.L.latLngBounds([])

      map.eachLayer((layer) => {
        try {
          if (typeof layer.getLatLng === 'function') {
            const latlng = layer.getLatLng()
            if (latlng && Number.isFinite(latlng.lat) && Number.isFinite(latlng.lng)) {
              bounds.extend(latlng)
            }
            return
          }

          if (typeof layer.getBounds === 'function') {
            const layerBounds = layer.getBounds()
            if (layerBounds && typeof layerBounds.isValid === 'function' && layerBounds.isValid()) {
              bounds.extend(layerBounds)
            }
          }
        } catch {
          // no-op
        }
      })

      if (bounds.isValid()) {
        map.fitBounds(bounds, { padding: [20, 20], maxZoom: 17, animate: false })
      }
    } catch {
      // no-op
    }
  }, [])

  const scheduleRecenter = useCallback(() => {
    clearTimers()
    ;[40, 180, 520, 1100].forEach((delay) => {
      const timerId = window.setTimeout(() => {
        recenterFromLayers()
      }, delay)
      timersRef.current.push(timerId)
    })
  }, [clearTimers, recenterFromLayers])

  useEffect(() => {
    return () => {
      clearTimers()
    }
  }, [clearTimers])

  if (!html) {
    return <div className="empty-box">Mapa indisponivel.</div>
  }

  return (
    <iframe
      key={frameKey}
      ref={iframeRef}
      title="mapa"
      className="map-frame"
      srcDoc={html}
      sandbox="allow-scripts allow-same-origin allow-popups"
      onLoad={scheduleRecenter}
    />
  )
}
