"use client"; import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react"; import { usePathname } from "next/navigation"; type Ctx = { ids: Set; has: (id: number) => boolean; toggle: (id: number) => void; selectMany: (ids: number[]) => void; clear: () => void; visibleIds: number[]; setVisibleIds: (ids: number[]) => void; }; const SelectCtx = createContext(null); export function SelectionProvider({ children }: { children: React.ReactNode }) { const [ids, setIds] = useState>(new Set()); const [visibleIds, setVisibleIdsState] = useState([]); // Guard against fresh-array identity churn: server-side renders pass a new // `number[]` reference every time, which would otherwise re-fire all consumers. const setVisibleIds = useCallback((next: number[]) => { setVisibleIdsState((cur) => { if (cur.length === next.length && cur.every((v, i) => v === next[i])) return cur; return next; }); }, []); const toggle = useCallback((id: number) => setIds((cur) => { const next = new Set(cur); if (next.has(id)) next.delete(id); else next.add(id); return next; }), []); const selectMany = useCallback((newIds: number[]) => setIds((cur) => { const next = new Set(cur); newIds.forEach((i) => next.add(i)); return next; }), []); const clear = useCallback(() => setIds(new Set()), []); // Global route-change cleanup: pages without RegisterVisible (e.g. // /actress, /category, /tag, /search) would otherwise carry stale // selections across navigation. Clear on any pathname change. const pathname = usePathname(); const lastPath = useRef(null); useEffect(() => { if (lastPath.current !== null && lastPath.current !== pathname) { setIds(new Set()); setVisibleIdsState([]); } lastPath.current = pathname; }, [pathname]); const value = useMemo(() => ({ ids, has: (id) => ids.has(id), toggle, selectMany, clear, visibleIds, setVisibleIds, }), [ids, toggle, selectMany, clear, visibleIds, setVisibleIds]); return {children}; } export function useSelection() { const ctx = useContext(SelectCtx); if (!ctx) throw new Error("useSelection must be used within SelectionProvider"); return ctx; }