// Exercise 1: stabilize a handler passed to a memoized child (basics)
//
// `IncrementButton` is wrapped in React.memo, but `Counter` passes it a
// brand-new `handleIncrement` function every render, so React.memo can never
// help — the button re-renders every time Counter does, even from unrelated
// state changes.
//
// TODO 1: implement makeIncrementedValue (pure, no hooks)
// TODO 2: wrap handleIncrement in useCallback with the correct dependencies

import { memo, useCallback, useState } from "react";

let buttonRenderCount = 0; // test hook: counts IncrementButton renders

// TODO 1: given the current value, return the value after one increment.
function makeIncrementedValue(current: number): number {
  return current; // TODO: return current + 1
}

const IncrementButton = memo(function IncrementButton({ onClick }: { onClick: () => void }) {
  buttonRenderCount++;
  return <button onClick={onClick}>+1</button>;
});

function Counter() {
  const [count, setCount] = useState(0);
  const [unrelatedTick, setUnrelatedTick] = useState(0);

  // TODO 2: wrap this in useCallback([]) so IncrementButton doesn't
  // re-render when only `unrelatedTick` changes. Use the functional updater
  // form so `[]` deps are actually correct (no stale closure over `count`).
  const handleIncrement = () => {
    setCount((prev) => makeIncrementedValue(prev));
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setUnrelatedTick((t) => t + 1)}>
        Unrelated re-render ({unrelatedTick})
      </button>
      <IncrementButton onClick={handleIncrement} />
    </div>
  );
}

export { Counter, IncrementButton, makeIncrementedValue, buttonRenderCount };

// --- self-check: do not modify below this line ---
const check1 = makeIncrementedValue(0) === 1;
const check2 = makeIncrementedValue(41) === 42;
console.log(check1 && check2 ? "PASS (makeIncrementedValue)" : "FAIL (makeIncrementedValue)");

// Verify visually: mount <Counter />, click "Unrelated re-render" several
// times. Before fixing TODO 2, `buttonRenderCount` increments on every
// click. After wrapping handleIncrement in useCallback([]), it should stay
// fixed across those clicks (IncrementButton only re-renders when its own
// onClick prop reference actually changes, which it now never does).
