import type { ZoomControl } from './types'
import { useMapStore } from './providers/map/provider'
import { useCallback } from 'react'

/**
 * Higher-Order Component that provides zoom management capabilities through a render props pattern,
 * including zoom state, smooth transitions, loading states, and flyTo operations.
 *
 * @remarks
 * This component does not render any UI elements. It provides zoom state and control functions
 * through render props, allowing you to create custom zoom interfaces with complete design freedom.
 *
 * @example
 * ```tsx
 * <ZoomControls mapId="my-map">
 *   {({ zoom, setZoom, maxZoom, minZoom, isLoading }) => (
 *     <div>
 *       <button onClick={() => setZoom(zoom + 1)} disabled={zoom >= maxZoom || isLoading}>Zoom In</button>
 *       <span>Zoom: {Math.round(zoom * 100) / 100}</span>
 *       <button onClick={() => setZoom(zoom - 1)} disabled={zoom <= minZoom || isLoading}>Zoom Out</button>
 *     </div>
 *   )}
 * </ZoomControls>
 * ```
 */
export function ZoomControls({ children, mapId }: ZoomControl) {
  const { zoom, maxZoom, minZoom } = useMapStore(
    (state) => state.viewStates[mapId]!,
  )
  const isLoaded = useMapStore((state) => state.areLayersLoaded[mapId])

  const setZoom = useMapStore((state) => state.setZoom)
  const flyTo = useMapStore((state) => state.flyTo)
  const resetViewState = useMapStore((state) => state.resetViewState)

  return children({
    zoom,
    maxZoom,
    minZoom,
    isLoading: !isLoaded,
    setZoom: useCallback((zoom) => setZoom(mapId, zoom), [mapId, setZoom]),
    flyTo: useCallback(
      (viewState: Parameters<typeof flyTo>[1]) => flyTo(mapId, viewState),
      [flyTo, mapId],
    ),
    resetViewState: useCallback(
      () => resetViewState(mapId),
      [resetViewState, mapId],
    ),
  })
}
