import type { ServerGameStateMessage, ServerStoneTrajectory, ServerMessageTyped as ServerMessage, Team, } from './protocol' const WS_URL = import.meta.env.VITE_WS_URL function resolveWsUrl(): string { if (WS_URL) return WS_URL const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:' return `${protocol}//${window.location.hostname}:3000/ws` } export interface NetCallbacks { onJoined: (room: string) => void onWaiting: (message: string) => void onGameState: (msg: ServerGameStateMessage) => void onTrajectory: (paths: ServerStoneTrajectory[]) => void onEndScored: (end: number, points: number, scoringTeam: Team | null) => void onGameOver: (scores: number[], winner: Team | null) => void onError: (message: string) => void onClose: () => void } let socket: WebSocket | null = null export function connect(room: string, callbacks: NetCallbacks): void { if (socket) return const url = `${resolveWsUrl()}?room=${encodeURIComponent(room)}` const ws = new WebSocket(url) ws.onopen = () => { socket = ws } ws.onmessage = (event) => { try { const msg = JSON.parse(event.data) as ServerMessage if (!msg || typeof msg.type !== 'string') return switch (msg.type) { case 'joined': callbacks.onJoined(msg.room) break case 'waiting': callbacks.onWaiting(msg.message) break case 'game_state': callbacks.onGameState(msg) break case 'trajectory': callbacks.onTrajectory(msg.paths) break case 'end_scored': callbacks.onEndScored(msg.end, msg.points, msg.scoring_team ?? null) break case 'game_over': callbacks.onGameOver(msg.scores, msg.winner) break case 'error': callbacks.onError(msg.message) break } } catch (err) { console.error('Failed to parse server message', err) } } ws.onclose = () => { socket = null callbacks.onClose() } ws.onerror = () => {} } export function sendThrow( team: Team, broomX: number, broomY: number, weight: number, curl: number, friction: number, ): void { if (!socket || socket.readyState !== WebSocket.OPEN) return socket.send( JSON.stringify({ type: 'throw', team, broom_x: broomX, broom_y: broomY, weight, curl, friction, }), ) }