import { Children, isValidElement, type ReactNode } from 'react';
import { Reveal, type RevealProps } from './Reveal.js';

export interface StaggerListProps
  extends Omit<RevealProps, 'children' | 'delay'> {
  children: ReactNode;
  /** Delay between successive children (ms). Default 60. */
  stagger?: number;
  /** Initial delay applied to the first child (ms). Default 0. */
  initialDelay?: number;
  /** Element used as the list root. Default 'div'. */
  as?: 'div' | 'ul' | 'ol' | 'section';
}

/**
 * Reveal a list of children with a per-item delay. Each child is wrapped
 * in a `<Reveal>` so the same motion vocabulary applies — `from`,
 * `spring`, `duration`, `once`, etc. all flow through.
 *
 * @example
 * ```tsx
 * <StaggerList from="up" stagger={70}>
 *   {items.map((item) => <Card key={item.id} {...item} />)}
 * </StaggerList>
 * ```
 */
export function StaggerList({
  children,
  stagger = 60,
  initialDelay = 0,
  as: As = 'div',
  ...reveal
}: StaggerListProps) {
  const items = Children.toArray(children).filter(isValidElement);
  return (
    <As data-testid="bl-stagger-list">
      {items.map((child, i) => (
        <Reveal
          key={(child as { key?: string | number }).key ?? i}
          delay={initialDelay + i * stagger}
          {...reveal}
        >
          {child}
        </Reveal>
      ))}
    </As>
  );
}
