import { useCallback, useMemo } from 'react'
import { useLayerStore } from './providers/layers/store'
import { sortLayers } from './utils/sort-layers'
import type { Layer, LayerLegend } from './providers/layers/types'

/**
 * Provides legend data and interaction handlers for the specified layers, enabling visibility, opacity, and collapse control.
 *
 * @param layersId - Array of layer identifiers to include in the legend.
 * @param callback - Mapping function that transforms each layer into the desired legend data shape (e.g., `mappingLegendMeridian`).
 * @returns An object containing `legend` data and callbacks `onChangeVisibility`, `onChangeOpacity`, and `onChangeRowCollapse`.
 *
 * @example
 * ```tsx
 * const { legend, onChangeOpacity, onChangeVisibility, onChangeRowCollapse } =
 *   useLegend([LAYER_ID], mappingLegendMeridian)
 * ```
 *
 * @deprecated Legend state is moving into the react-ui legend module, which
 * owns the legend store and its setters. Prefer the store-backed `Legend`
 * components from `@carto/ps-react-ui/legend` (and `…/legend/stores`). This
 * hook will be removed once the react-ui ↔ react-maps store-sync adapter
 * lands; until then it remains functional.
 */
export function useLegend<T>(
  layersId: string[],
  callback: (layer: Layer) => T,
) {
  const layers = useLayerStore((state) => state.layers)
  const setLayer = useLayerStore((state) => state.setLayer)

  const layersById = useMemo(() => {
    return sortLayers(
      layersId.map((id) => layers[id]).filter((l): l is Layer => !!l?.legend),
    ).toReversed()
  }, [layers, layersId])

  const legend = useMemo(() => {
    return layersById.map(callback)
  }, [callback, layersById])

  const onChangeVisibility = useCallback(
    ({
      id,
      visible,
      ...legend
    }: {
      id: string
      visible: boolean
    } & Partial<LayerLegend>) => {
      setLayer(id, {
        props: { visible },
        legend,
      })
    },
    [setLayer],
  )

  const onChangeRowCollapse = useCallback(
    ({ id, collapsed }: { id: string; collapsed: boolean }) => {
      setLayer(id, {
        legend: {
          collapsed,
        },
      })
    },
    [setLayer],
  )

  const onChangeOpacity = useCallback(
    ({ id, opacity }: { id: string; opacity: number }) => {
      setLayer(id, {
        props: { opacity },
      })
    },
    [setLayer],
  )

  return {
    legend,
    onChangeVisibility,
    onChangeOpacity,
    onChangeRowCollapse,
  }
}
