import { IconButton } from '@mui/material'
import { CheckBoxOutlined } from '@mui/icons-material'
import { useCallback, useEffect } from 'react'
import type { LockSelectionProps, LockSelectionState } from './types'
import { actionButtonStyles } from '../shared/styles'
import { Tooltip } from '../../../components'
import { widgetStoreActions } from '../../stores/widget-store'
import { useWidgetSelector } from '../../stores/use-widget-selector'
import type { EchartWidgetData } from '../../echart/types'
export const LOCK_SELECTION_TOOL_ID = 'lock-selection'
/**
* Widget action button to lock the current selection.
*
* When locked, the widget data is filtered to only show the selected items.
* The button is only visible when there are selected items.
* Registers a transformation tool in the widget pipeline when mounted.
*
* @example
* ```tsx
*
* ```
*/
export function LockSelection({
id,
selectedItems,
order = 30,
labels,
Icon,
IconButtonProps,
}: LockSelectionProps) {
const { storeIsLocked } = useWidgetSelector(id, (w) => ({
storeIsLocked: (w as LockSelectionState | undefined)?.isLocked,
}))
const isLocked = storeIsLocked ?? false
// Register tool once — fn reads lockedItems from the store at execution time
useEffect(() => {
widgetStoreActions.registerTool(id, {
id: LOCK_SELECTION_TOOL_ID,
order,
enabled: false,
fn: (data) => {
const widget = widgetStoreActions.getWidget(id)
const items = widget?.lockedItems ?? []
if (items.length === 0) return data
return filterDataByLockedItems(data as EchartWidgetData, items)
},
})
return () => widgetStoreActions.unregisterTool(id, LOCK_SELECTION_TOOL_ID)
}, [id, order])
// Sync enabled from store — lightweight, no re-registration.
// When selectedItems is empty (e.g., remount with no active selection),
// disable the tool and clear stale lock state.
useEffect(() => {
if (isLocked && selectedItems.length === 0) {
widgetStoreActions.setWidget(id, { isLocked: false, lockedItems: [] })
return
}
widgetStoreActions.setToolEnabled(id, LOCK_SELECTION_TOOL_ID, isLocked)
}, [id, isLocked, selectedItems.length])
const handleToggle = useCallback(() => {
if (isLocked) {
// Unlock: clear locked items and disable tool
widgetStoreActions.setWidget(id, {
isLocked: false,
lockedItems: [],
})
} else {
// Lock: save selected items and enable tool
widgetStoreActions.setWidget(id, {
isLocked: true,
lockedItems: selectedItems,
})
}
}, [id, isLocked, selectedItems])
// Don't render if no selections
if (selectedItems.length === 0) {
return null
}
const tooltipLabel = isLocked
? (labels?.unlock ?? 'Unlock selection')
: (labels?.lock ?? 'Lock selection')
const ariaLabel = labels?.ariaLabel ?? tooltipLabel
return (
{Icon ?? }
)
}
/**
* Filters widget data to only include items with names matching the locked items.
*/
function filterDataByLockedItems(
data: EchartWidgetData,
lockedItems: string[],
): EchartWidgetData {
return data.map((series) =>
series.filter((item) => {
const name = item.name
return typeof name === 'string' && lockedItems.includes(name)
}),
)
}