// Button with physical press (squash + spring release), hover lift, and an
// optional attention jump on click. Personality comes from the nearest MotionProvider.
import { useMemo, type ButtonHTMLAttributes } from "react";
import { jump } from "twelve-principles";
import { mergeRefs, useHover, useMotion, usePress } from "twelve-principles/react";

export interface MotionButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  /** Play a small jump (anticipation + squash & stretch) after each click. */
  bounceOnClick?: boolean;
}

export function MotionButton({ bounceOnClick = false, onClick, ...rest }: MotionButtonProps) {
  const motion = useMotion<HTMLButtonElement>();
  const press = usePress<HTMLButtonElement>();
  const hover = useHover<HTMLButtonElement>({ level: 4 });
  // Stable merged ref: an inline mergeRefs() would detach/attach the behaviours every render.
  const ref = useMemo(() => mergeRefs(motion.ref, press, hover), [motion.ref, press, hover]);
  return (
    <button
      {...rest}
      ref={ref}
      onClick={(event) => {
        onClick?.(event);
        if (bounceOnClick) motion.play((p) => jump({ personality: p, height: 8 }));
      }}
    />
  );
}
