import {
  Children,
  isValidElement,
  type ReactElement,
  type ReactNode,
} from 'react'
import { Box } from '@mui/material'
import { useLegendRow } from '../contexts'
import { styles } from './styles'

export interface LegendActionsProps {
  children?: ReactNode
}

/**
 * Header actions slot for `Legend.Row` / `Legend.Group` (widgets-v2 `Actions`
 * parity): the wrapper partitions its children by component identity and
 * renders this slot inside the header, wrapped in the hover-fade group
 * (`PsLegend-rowFade` in rows, `PsLegend-groupFade` in group headers —
 * resolved from the nearest context). Compose the visibility toggle last so
 * it sits rightmost, per design.
 *
 * @experimental This API is new and may change in a future release.
 */
export function LegendActions({ children }: LegendActionsProps) {
  const inRow = useLegendRow() !== null
  return (
    <Box
      className={inRow ? 'PsLegend-rowFade' : 'PsLegend-groupFade'}
      sx={styles.fadeGroup}
    >
      {children}
    </Box>
  )
}

/**
 * Splits a wrapper's children by component identity: `<Legend.Actions>`
 * elements belong in the header, everything else in the collapsible body.
 * Identity comparison works because consumers import the slot from the same
 * module (same pattern as widgets-v2 `Wrapper`).
 */
export function partitionLegendChildren(children: ReactNode): {
  actions: ReactNode[]
  body: ReactNode[]
} {
  const actions: ReactNode[] = []
  const body: ReactNode[] = []
  for (const child of Children.toArray(children)) {
    if (isSlot(child, LegendActions)) actions.push(child)
    else body.push(child)
  }
  return { actions, body }
}

function isSlot(node: ReactNode, type: unknown): node is ReactElement {
  return isValidElement(node) && node.type === type
}
