// Exercise 4: useDeferredValue staleness tracking (theory 2, Section 5)
//
// SearchResults should dim its content while showing results for an OLD
// query because a new one is still being computed in the background. The
// staleness check itself — comparing the live value to the deferred one —
// is pure logic separate from the hook plumbing.
//
// STEP 1: implement isStale(liveValue, deferredValue) — PURE, just an
//         inequality check, but named clearly so the intent reads well at
//         call sites.
// STEP 2: implement filterHugeList(items, query) — a PURE filter used as
//         the (deliberately!) expensive derived computation that
//         useDeferredValue exists to avoid blocking on.
// STEP 3: wire useDeferredValue(query) and useMemo in SearchResults so the
//         expensive filter only reruns when the DEFERRED query changes, not
//         on every keystroke.

import { useDeferredValue, useMemo, useState } from "react";

interface Item {
  id: string;
  name: string;
}

// STEP 1: pure — is the live value currently ahead of the deferred value?
function isStale(liveValue: string, deferredValue: string): boolean {
  // TODO: return liveValue !== deferredValue
  return false; // placeholder
}

// STEP 2: pure filter — case-insensitive substring match on `name`
function filterHugeList(items: Item[], query: string): Item[] {
  // TODO: return items whose name includes query, case-insensitively
  return items; // placeholder — no filtering happens yet
}

function SearchResults({ items }: { items: Item[] }) {
  const [query, setQuery] = useState("");
  // TODO STEP 3: const deferredQuery = useDeferredValue(query);
  const deferredQuery = query; // placeholder — not actually deferred yet

  // TODO STEP 3: useMemo(() => filterHugeList(items, deferredQuery), [items, deferredQuery])
  const results = filterHugeList(items, deferredQuery);
  const stale = isStale(query, deferredQuery);

  return (
    <div style={{ opacity: stale ? 0.6 : 1 }}>
      <input value={query} onChange={(e) => setQuery(e.target.value)} />
      <ul>{results.map((r) => <li key={r.id}>{r.name}</li>)}</ul>
    </div>
  );
}

export { isStale, filterHugeList, SearchResults };

// --- self-check: do not modify below this line ---
console.log(isStale("abc", "ab") ? "PASS (mismatched values flagged stale)" : "FAIL (mismatched values flagged stale)");
console.log(isStale("abc", "abc") ? "FAIL (matching values wrongly flagged stale)" : "PASS (matching values are not stale)");

const items: Item[] = [
  { id: "1", name: "Laptop" },
  { id: "2", name: "Lamp" },
  { id: "3", name: "Desk" },
];

const laptopMatch = filterHugeList(items, "lap");
console.log(
  laptopMatch.length === 1 && laptopMatch[0].name === "Laptop"
    ? "PASS (case-insensitive substring match)"
    : "FAIL (case-insensitive substring match)",
);

const lMatches = filterHugeList(items, "L");
console.log(
  lMatches.length === 2 ? "PASS (matches multiple items sharing a substring)" : "FAIL (matches multiple items sharing a substring)",
);

const emptyQuery = filterHugeList(items, "");
console.log(emptyQuery.length === 3 ? "PASS (empty query returns everything)" : "FAIL (empty query returns everything)");

const noMatch = filterHugeList(items, "zzz");
console.log(noMatch.length === 0 ? "PASS (no match returns empty array)" : "FAIL (no match returns empty array)");

// Verify visually: render SearchResults with a large `items` array and an
// artificially slowed filterHugeList (e.g. a busy-loop). BEFORE finishing
// STEP 3, every keystroke blocks until filtering completes — typing feels
// laggy. AFTER wiring useDeferredValue + useMemo, the input stays responsive
// immediately on each keystroke, the list visibly dims (isStale) for a beat,
// then updates once the deferred value catches up.
