'use client'

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

let socket: Socket | null = null
let currentRoom: string | null = null

export type SocketStatus = 'connected' | 'disconnected' | 'reconnecting'
type StatusListener = (status: SocketStatus) => void

let currentStatus: SocketStatus = 'disconnected'
const statusListeners = new Set<StatusListener>()

function setStatus(status: SocketStatus) {
  if (status === currentStatus) return
  currentStatus = status
  statusListeners.forEach(fn => fn(status))
}

/** Subscribe to socket connection status changes. Returns an unsubscribe function. */
export function onSocketStatus(listener: StatusListener): () => void {
  statusListeners.add(listener)
  // Immediately notify current status
  listener(currentStatus)
  return () => { statusListeners.delete(listener) }
}

/** Get current socket connection status */
export function getSocketStatus(): SocketStatus {
  return currentStatus
}

export function getSocket(): Socket {
  if (!socket) {
    socket = io({
      path: '/socket.io',
      transports: ['websocket', 'polling'],
      upgrade: true,
      reconnection: true,
      reconnectionAttempts: Infinity,
      reconnectionDelay: 1000,
      reconnectionDelayMax: 5000,
      timeout: 10000,
      forceNew: false,
    })
    socket.on('connect', () => {
      console.log('[Socket.io] Connected:', socket?.id)
      setStatus('connected')
      // Re-join project room after reconnect
      if (currentRoom) {
        console.log('[Socket.io] Re-joining room:', currentRoom)
        socket?.emit('join-project', currentRoom)
      }
    })
    socket.on('disconnect', (reason) => {
      console.warn('[Socket.io] Disconnected:', reason)
      setStatus('disconnected')
      if (reason === 'io server disconnect') {
        // Server disconnected us, need to manually reconnect
        socket?.connect()
      }
    })
    socket.on('connect_error', (err) => {
      console.warn('[Socket.io] Connection error:', err.message)
    })
    socket.io.on('reconnect', (attempt) => {
      console.log('[Socket.io] Reconnected after', attempt, 'attempts')
      setStatus('connected')
    })
    socket.io.on('reconnect_attempt', (attempt) => {
      console.log('[Socket.io] Reconnect attempt', attempt)
      setStatus('reconnecting')
    })
  }
  return socket
}

/** Track which room the socket should be in (for auto-rejoin on reconnect) */
export function setSocketRoom(projectId: string | null): void {
  currentRoom = projectId
}
