import { create } from 'zustand'
import type { LayerStore } from './types'
import type { LayerExtension } from '@deck.gl/core'

/**
 * Zustand store for centralized layer state management, providing methods to add, update, remove, and query deck.gl layers.
 *
 * @remarks
 * Layer properties are shallow-merged on `setLayer`, with `extensions` deduplicated and `updateTriggers` deep-merged.
 * Use selective subscriptions to prevent unnecessary re-renders (e.g., `useLayerStore((state) => state.layers)`).
 */
export const useLayerStore = create<LayerStore>((set, get) => ({
  layers: {},
  setLayer: (id, layer) =>
    set((state) => {
      const layers = { ...state.layers }

      const _layer = layers[id] ?? { type: null, props: {} }

      const extensions = [
        ...(_layer.props.extensions ?? []),
        ...(layer.props?.extensions ?? []),
      ].reduce((acc, extension) => {
        if (!acc.some((e) => e.equals(extension))) {
          acc.push(extension)
        }
        return acc
      }, [] as LayerExtension[])

      const legend =
        !!_layer.legend || !!layer.legend
          ? {
              ..._layer.legend,
              ...layer.legend,
            }
          : undefined

      layers[id] = {
        ..._layer,
        ...layer,
        props: {
          id,
          ..._layer.props,
          ...layer.props,
          updateTriggers: {
            ...(_layer.props.updateTriggers ?? {}),
            ...(layer.props?.updateTriggers ?? {}),
          },
          extensions,
        },
        legend,
      }

      return { layers }
    }),
  removeLayer: (id) =>
    set((state) => {
      const layers = { ...state.layers }
      delete layers[id]
      return { layers }
    }),
  getLayers: () => get().layers,
  getLayer: (id) => get().layers[id],
}))
