// Exercise 1: memoize an expensive filter (basics)
//
// `expensiveFilter` simulates a costly computation (it busy-loops so its
// cost is visible). `ProductList` currently recomputes it on every render,
// even when `onlyProducts`/`query` haven't changed — for example, when the
// unrelated `renderCount` state ticks up.
//
// TODO 1: implement isMatch(product, query) — pure, no hooks
// TODO 2: wrap the filtering work in useMemo with the correct dependencies

import { useMemo, useState } from "react";

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

// simulates real work so the cost of skipping/not-skipping it is meaningful
function expensiveFilter(products: Product[], query: string): Product[] {
  let busy = 0;
  for (let i = 0; i < 2_000_000; i++) busy += i; // pretend this work is costly
  return products.filter((p) => isMatch(p, query));
}

// TODO 1: return true if `product.name` contains `query`, case-insensitively
function isMatch(product: Product, query: string): boolean {
  return false; // TODO: implement using .toLowerCase().includes(...)
}

function ProductList({ products, query }: { products: Product[]; query: string }) {
  const [renderCount, setRenderCount] = useState(0);

  // TODO 2: wrap this call in useMemo([products, query]) so clicking the
  // "force re-render" button below does NOT re-run expensiveFilter
  const filtered = expensiveFilter(products, query);

  return (
    <div>
      <button onClick={() => setRenderCount((c) => c + 1)}>
        Force re-render ({renderCount})
      </button>
      <ul>
        {filtered.map((p) => (
          <li key={p.id}>{p.name}</li>
        ))}
      </ul>
    </div>
  );
}

export { ProductList, isMatch, expensiveFilter };

// --- self-check: do not modify below this line ---
const shoe = { id: "1", name: "Running Shoe" };
const hat = { id: "2", name: "Winter Hat" };

const check1 = isMatch(shoe, "shoe") === true;
const check2 = isMatch(shoe, "SHOE") === true;
const check3 = isMatch(hat, "shoe") === false;

console.log(check1 && check2 && check3 ? "PASS (isMatch)" : "FAIL (isMatch)");

// Verify visually: click "Force re-render" repeatedly with React DevTools'
// profiler (or a console.log inside expensiveFilter) — after fixing TODO 2,
// expensiveFilter should NOT log again on those clicks, only when
// `products` or `query` actually change.
