import * as React from "react";

const SWIPE_THRESHOLD = -40;
const SWIPE_OPEN = -84;

/** Module-wide pub/sub so opening one row closes every other open row (mirrors the source app's schliesseAlleSwipes()). */
const listeners = new Set<() => void>();
function closeAllExcept(keep: () => void) {
  for (const close of listeners) {
    if (close !== keep) close();
  }
}

export interface SwipeRowProps {
  children: React.ReactNode;
  onDelete: () => void;
  deleteLabel?: string;
  /** Controlled swiped-open state. */
  swiped?: boolean;
  onSwipedChange?: (swiped: boolean) => void;
  className?: string;
}

export function SwipeRow({
  children,
  onDelete,
  deleteLabel = "Delete",
  swiped,
  onSwipedChange,
  className,
}: SwipeRowProps) {
  const [internalSwiped, setInternalSwiped] = React.useState(false);
  const isControlled = swiped !== undefined;
  const isSwiped = isControlled ? swiped : internalSwiped;

  const setSwiped = React.useCallback(
    (next: boolean) => {
      if (!isControlled) setInternalSwiped(next);
      onSwipedChange?.(next);
    },
    [isControlled, onSwipedChange]
  );

  const close = React.useCallback(() => setSwiped(false), [setSwiped]);

  React.useEffect(() => {
    listeners.add(close);
    return () => {
      listeners.delete(close);
    };
  }, [close]);

  const dragStartX = React.useRef<number | null>(null);

  const onPointerDown = (e: React.PointerEvent) => {
    dragStartX.current = e.clientX;
  };

  const onPointerMove = (e: React.PointerEvent) => {
    if (dragStartX.current === null) return;
    const delta = e.clientX - dragStartX.current;
    if (delta < SWIPE_THRESHOLD) {
      closeAllExcept(close);
      setSwiped(true);
      dragStartX.current = null;
    } else if (delta > -SWIPE_THRESHOLD) {
      setSwiped(false);
    }
  };

  const onPointerUp = () => {
    dragStartX.current = null;
  };

  const classes = ["ads-swipe-wrap"];
  if (className) classes.push(className);

  return (
    <div className={classes.join(" ")}>
      <button type="button" className="ads-swipe-delete" onClick={onDelete}>
        {deleteLabel}
      </button>
      <div
        className={isSwiped ? "ads-swipe-content ads-swiped" : "ads-swipe-content"}
        style={{ transform: isSwiped ? `translateX(${SWIPE_OPEN}px)` : undefined }}
        onPointerDown={onPointerDown}
        onPointerMove={onPointerMove}
        onPointerUp={onPointerUp}
        onPointerCancel={onPointerUp}
      >
        {children}
      </div>
    </div>
  );
}
