"use client";

import * as React from "react";

/** True for `ms` after `value` changes (never on first render). Drives the "this just updated" flash. */
export function useChanged(value: unknown, ms = 1300) {
  const [changed, setChanged] = React.useState(false);
  const first = React.useRef(true);
  const prev = React.useRef(value);
  React.useEffect(() => {
    if (first.current) {
      first.current = false;
      prev.current = value;
      return;
    }
    if (Object.is(prev.current, value)) return;
    prev.current = value;
    setChanged(true);
    const t = setTimeout(() => setChanged(false), ms);
    return () => clearTimeout(t);
  }, [value, ms]);
  return changed;
}

/** Re-renders every `ms` so relative timestamps ("updated 12s ago") keep ticking. */
export function useTick(ms = 5000) {
  const [, setN] = React.useState(0);
  React.useEffect(() => {
    const t = setInterval(() => setN((n) => n + 1), ms);
    return () => clearInterval(t);
  }, [ms]);
}

/** Pull-to-refresh for phone pages: returns the current pull distance and whether a refresh was triggered. */
export function usePullToRefresh(onRefresh: () => void, threshold = 84) {
  const [pull, setPull] = React.useState(0);
  const [busy, setBusy] = React.useState(false);
  const startY = React.useRef<number | null>(null);
  React.useEffect(() => {
    const onStart = (e: TouchEvent) => {
      startY.current = window.scrollY <= 0 ? e.touches[0].clientY : null;
    };
    const onMove = (e: TouchEvent) => {
      if (startY.current == null) return;
      const dy = e.touches[0].clientY - startY.current;
      if (dy <= 0 || window.scrollY > 0) return setPull(0);
      setPull(Math.min(140, dy * 0.6));
    };
    const onEnd = () => {
      if (startY.current == null) return;
      setPull((p) => {
        if (p >= threshold) {
          setBusy(true);
          onRefresh();
          setTimeout(() => setBusy(false), 1200);
        }
        return 0;
      });
      startY.current = null;
    };
    window.addEventListener("touchstart", onStart, { passive: true });
    window.addEventListener("touchmove", onMove, { passive: true });
    window.addEventListener("touchend", onEnd);
    return () => {
      window.removeEventListener("touchstart", onStart);
      window.removeEventListener("touchmove", onMove);
      window.removeEventListener("touchend", onEnd);
    };
  }, [onRefresh, threshold]);
  return { pull, busy, ready: pull >= threshold };
}
