"use client"; import { useState, useCallback, useRef, useEffect } from "react"; import { MatchmakingManager, type MatchFoundData, } from "@/lib/game/matchmaking"; /** The current phase of the matchmaking flow. */ export type MatchmakingState = "idle" | "searching" | "found" | "error"; /** * React hook that wraps `MatchmakingManager` with component-friendly state. * * Returns reactive `state`, `playerCount`, `matchData`, and `error` values * alongside `startSearching` / `cancelSearch` actions. * * Automatically cleans up the matchmaking channel on unmount. */ export function useMatchmaking( playerId: string, playerName: string, playerElo: number, ) { const [state, setState] = useState("idle"); const [playerCount, setPlayerCount] = useState(0); const [matchData, setMatchData] = useState(null); const [error, setError] = useState(null); const managerRef = useRef(null); const startSearching = useCallback(async () => { setState("searching"); setError(null); const manager = new MatchmakingManager(playerId, playerName, playerElo); managerRef.current = manager; await manager.joinQueue({ onPlayerCount: setPlayerCount, onMatchFound: (data) => { setState("found"); setMatchData(data); }, onError: (err) => { setState("error"); setError(err); }, }); }, [playerId, playerName, playerElo]); const cancelSearch = useCallback(async () => { if (managerRef.current) { await managerRef.current.leaveQueue(); managerRef.current = null; } setState("idle"); setMatchData(null); }, []); // Cleanup on unmount useEffect(() => { return () => { managerRef.current?.leaveQueue(); }; }, []); return { state, playerCount, matchData, error, startSearching, cancelSearch }; }