import { io, Socket } from 'socket.io-client';

/**
 * Prefer same-origin WS URL (proxied by nginx) so Cloudflare / cross-host
 * WebSocket failures on the API domain do not break live scores.
 * Falls back to NEXT_PUBLIC_WS_URL, then API host.
 */
function resolveWsUrl(): string {
  if (typeof window !== 'undefined') {
    // Same origin — nginx /socket.io/ → backend :4600
    return window.location.origin;
  }
  return process.env.NEXT_PUBLIC_WS_URL || process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:4600';
}

let socket: Socket | null = null;

export function getSocket(): Socket {
  if (!socket && typeof window !== 'undefined') {
    socket = io(resolveWsUrl(), {
      // Polling first: reliable behind Cloudflare; upgrade to WS when available
      transports: ['polling', 'websocket'],
      upgrade: true,
      withCredentials: true,
      autoConnect: true,
      reconnection: true,
      reconnectionAttempts: 15,
      reconnectionDelay: 1000,
      timeout: 12000,
    });
  }
  return socket!;
}

export function subscribeToMatch(matchId: string, onUpdate: (data: any) => void) {
  const s = getSocket();
  if (!s) return () => {};

  const join = () => s.emit('join_match', matchId);
  if (s.connected) join();
  else s.once('connect', join);

  const handleScoreUpdate = (data: any) => {
    if (data.matchId === matchId) onUpdate(data);
  };

  const handleUndo = (data: any) => {
    if (data.matchId === matchId) onUpdate(data);
  };

  s.on('match:score_update', handleScoreUpdate);
  s.on('match:undo', handleUndo);

  return () => {
    s.emit('leave_match', matchId);
    s.off('match:score_update', handleScoreUpdate);
    s.off('match:undo', handleUndo);
  };
}
