// Exercise 2: previous-value tracker
//
// Implement `usePreviousValue<T>(value: T): T | undefined` — a small custom
// hook that returns whatever `value` WAS on the previous render (undefined
// on the very first render). The pattern: a ref holding the last-seen value,
// updated inside a useEffect that runs AFTER render (so during render, the
// ref still holds the previous render's value).
//
// Then implement `simulateRenders`, a PURE function that models what
// usePreviousValue should return across a sequence of renders, without any
// React involved — used to self-check the logic before trusting the hook.
//
// TODO 1: implement usePreviousValue
// TODO 2: implement simulateRenders (pure)

import { useEffect, useRef } from "react";

function usePreviousValue<T>(value: T): T | undefined {
  const ref = useRef<T | undefined>(undefined);

  useEffect(() => {
    // TODO 1: after this render commits, store the CURRENT value for next
    // time. This runs after the return statement below already executed,
    // so ref.current below still reflects the PREVIOUS render's value.
  });

  return ref.current; // TODO: this line is already correct once TODO 1 is done
}

function PriceTag({ price }: { price: number }) {
  const previousPrice = usePreviousValue(price);
  const direction =
    previousPrice === undefined ? "—" : price > previousPrice ? "up" : price < previousPrice ? "down" : "same";

  return (
    <p>
      ${price} ({direction})
    </p>
  );
}

// TODO 2: given a list of values representing what `value` was on each
// render in order, return an array of what usePreviousValue would have
// returned on each of those renders (undefined for the first one).
function simulateRenders<T>(values: T[]): (T | undefined)[] {
  return values.map(() => undefined); // TODO: shift each value one position later
}

export { usePreviousValue, PriceTag, simulateRenders };

// --- self-check: do not modify below this line ---
const result = simulateRenders([10, 20, 20, 5]);
const expected = [undefined, 10, 20, 20];
const matches = JSON.stringify(result) === JSON.stringify(expected);
console.log(matches ? "PASS (pure logic)" : `FAIL (pure logic) — got ${JSON.stringify(result)}`);

// Verify visually: mount <PriceTag price={x} /> and re-render it with
// changing `price` props (e.g. via a parent that updates state on a timer
// or button click) — the "(up)"/"(down)"/"(same)" label should always
// reflect the PREVIOUS price, one render behind the current one, and show
// "—" on the very first render.
