import type { KeyboardEvent } from 'react'
import { Box, Typography } from '@mui/material'
import { CategoryBarStacked } from './category-bar-stacked'
import type { CategoryKey, CategorySize } from '../types'
import { styles } from '../style'

export interface CategoryRowStackedProps {
  /** Raw category key — what gets emitted to `onToggle`. */
  name: CategoryKey
  /** Display label (post-`labelFormatter`). Falls back to `name`. */
  displayName?: string | number
  /** One value per series. Zero values still appear in the breakdown row. */
  values: readonly number[]
  /** One color per series (palette + per-series overrides resolved upstream). */
  colors: readonly string[]
  /** Series names for the breakdown row. Missing entries fall back to `Series N`. */
  seriesNames: readonly string[]
  formatter: (n: number) => string
  selected: boolean
  onToggle: (name: CategoryKey) => void
  /** Bar visual density. Forwarded to the inner {@link CategoryBarStacked}. */
  size?: CategorySize
}

/**
 * Stacked-mode category row: label + total share a header line; a single
 * segmented bar sits below; an inline breakdown lists each series with its
 * formatted value. Click anywhere in the row toggles selection by `name`.
 *
 * Per-row normalization: the stacked bar always fills 100% of the track,
 * with each segment sized as `value_i / sum(values)`. This is intentionally
 * different from `CategoryRowMulti` (which scales bars against the global
 * `maxValue` for cross-row comparison) — in stacked mode the comparable
 * axis is the proportion of each series within the row, not the row's
 * total relative to other rows. The total numeric value is still shown in
 * the header so the per-row magnitude isn't lost.
 *
 * Visual selection / dim signal lives entirely in the segment colors
 * (`colors` prop) — every series in a dimmed row receives
 * `theme.palette.action.disabled`. The bar visually collapses to a single
 * grey shape when dimmed, but the breakdown text stays at full color so the
 * per-series values remain legible.
 */
export function CategoryRowStacked({
  name,
  displayName,
  values,
  colors,
  seriesNames,
  formatter,
  selected,
  onToggle,
  size,
}: CategoryRowStackedProps) {
  const handleKey = (e: KeyboardEvent<HTMLDivElement>): void => {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault()
      onToggle(name)
    }
  }
  const total = values.reduce((a, b) => a + b, 0)
  return (
    <Box
      role='button'
      aria-pressed={selected}
      tabIndex={0}
      onClick={() => onToggle(name)}
      onKeyDown={handleKey}
      sx={styles.rowStacked}
    >
      <Box sx={styles.stackedHeader}>
        <Typography variant='body2' sx={styles.multiName}>
          {displayName ?? name}
        </Typography>
        <Typography variant='body2' sx={styles.stackedTotal}>
          {formatter(total)}
        </Typography>
      </Box>
      <CategoryBarStacked
        values={values}
        colors={colors}
        maxValue={total}
        size={size}
      />
      <Box sx={styles.stackedBreakdown}>
        {values.map((v, i) => (
          // Series name is the stable identity for the breakdown line.
          <Typography
            key={`breakdown-${seriesNames[i] ?? `series-${i}`}`}
            variant='body2'
            sx={styles.stackedBreakdownItem}
          >
            {`${seriesNames[i] ?? `Series ${i + 1}`}: ${formatter(v)}`}
          </Typography>
        ))}
      </Box>
    </Box>
  )
}
