import { useMemo, useState, type ReactNode } from 'react'
import { Box, Collapse, Typography } from '@mui/material'
import { ExpandMore as ExpandMoreIcon } from '@mui/icons-material'
import { SmartTooltip } from '../../../components/smart-tooltip/smart-tooltip'
import {
  selectLayerCollapsible,
  useLegendId,
  useLegendShallow,
  useLegendStore,
} from '../../stores'
import { accordionKeyDown } from '../a11y'
import {
  LegendRowContext,
  type LegendRowContextValue,
  useLegendGroupId,
} from '../contexts'
import { partitionLegendChildren } from '../legend-actions/legend-actions'
import { LEGEND_GROUP_HEADER_HEIGHT } from '../legend-group/styles'
import { useLegendSortable } from '../legend-sortable/contexts'
import {
  SortableEntity,
  type SortableEntityRenderProps,
} from '../legend-sortable/sortable-entity'
import { styles } from './styles'

export interface LegendRowProps {
  layerId: string
  /**
   * `<Legend.Actions>` in the sticky header; body children + `helperText` footer.
   * Place `<Legend.Opacity.Inline />` first in the body.
   */
  children?: ReactNode
}

/**
 * Store-connected layer row. Provides row context for actions; hidden layers
 * force-collapse the body.
 *
 * @experimental This API is new and may change in a future release.
 */
export function LegendRow({ layerId, children }: LegendRowProps) {
  const id = useLegendId()
  const layer = useLegendShallow(id, (s) => s.layers[layerId])
  const setCollapsed = useLegendShallow(id, (s) => s.setCollapsed)
  const collapsible = useLegendStore(id, (s) =>
    selectLayerCollapsible(s, layerId),
  )
  const inGroup = useLegendGroupId() !== null
  const sortable = useLegendSortable()

  const [opacityOpen, setOpacityOpen] = useState(false)
  // Hidden rows derive opacityOpen=false so menu `.active` never pins while hidden.
  const visible = layer?.visible ?? true
  const rowContext = useMemo<LegendRowContextValue>(
    () => ({ layerId, opacityOpen: opacityOpen && visible, setOpacityOpen }),
    [layerId, opacityOpen, visible],
  )

  if (!layer) return null

  const { actions, body } = partitionLegendChildren(children)
  const effectivelyCollapsed = !layer.visible || layer.collapsed
  const stickyTop = inGroup ? LEGEND_GROUP_HEADER_HEIGHT : 0
  const canToggle = layer.visible && collapsible
  const toggle = () => setCollapsed(layerId, !layer.collapsed)

  const renderRow = (sortableProps?: SortableEntityRenderProps) => (
    <LegendRowContext.Provider value={rowContext}>
      <Box
        ref={sortableProps?.rootRef}
        style={sortableProps?.rootStyle}
        sx={[
          styles.row,
          sortableProps?.dragging === true && styles.rowDragging,
        ]}
      >
        <Box
          sx={[styles.header, inGroup && styles.headerGrouped]}
          style={{ top: stickyTop }}
        >
          {sortableProps?.handle}
          <Box
            sx={[styles.titleBox, canToggle && styles.titleBoxInteractive]}
            {...(canToggle && {
              role: 'button',
              tabIndex: 0,
              'aria-expanded': !layer.collapsed,
              onClick: toggle,
              onKeyDown: accordionKeyDown(toggle),
            })}
          >
            <Box sx={styles.titleLine}>
              <SmartTooltip title={layer.name} dependencies={[layer.name]}>
                {({ ref }) => (
                  <Typography
                    ref={ref}
                    variant='button'
                    color={layer.visible ? 'text.primary' : 'text.disabled'}
                    sx={styles.title}
                  >
                    {layer.name}
                  </Typography>
                )}
              </SmartTooltip>
              {canToggle && (
                <ExpandMoreIcon
                  sx={[
                    styles.chevron,
                    layer.collapsed && styles.chevronCollapsed,
                  ]}
                />
              )}
            </Box>
            {layer.subtitle && !effectivelyCollapsed && (
              <Typography variant='caption' color='text.secondary'>
                {layer.subtitle}
              </Typography>
            )}
          </Box>

          <Box className='PsLegend-rowActions' sx={styles.actions}>
            {actions}
          </Box>
        </Box>

        <Collapse in={!effectivelyCollapsed}>
          <Box
            sx={[
              styles.content,
              inGroup && styles.contentGrouped,
              !layer.visible && styles.dimmed,
            ]}
          >
            {body}
          </Box>
          {layer.helperText && (
            <Box sx={[styles.footer, inGroup && styles.footerGrouped]}>
              {typeof layer.helperText === 'string' ? (
                <Typography variant='caption' color='text.secondary'>
                  {layer.helperText}
                </Typography>
              ) : (
                layer.helperText
              )}
            </Box>
          )}
        </Collapse>
      </Box>
    </LegendRowContext.Provider>
  )

  return sortable ? (
    <SortableEntity kind='layer' id={layerId} render={renderRow} />
  ) : (
    renderRow()
  )
}
