import { resolveEndpoints } from '@/config/endpoints'
import { useSessionState } from '@/stores/session-state'

let ws: WebSocket | null = null
let reconnectTimer: ReturnType<typeof setTimeout> | null = null
let reconnectDelay = 1000
const MAX_RECONNECT_DELAY = 15000

function connect() {
  const store = useSessionState()

  // Connect to terminal server (4103) — same base as terminal WS
  const url = resolveEndpoints().terminal
  console.log('[SessionStateWS] Connecting to', url)

  ws = new WebSocket(url)

  ws.onopen = () => {
    console.log('[SessionStateWS] Connected')
    store.setConnected(true)
    reconnectDelay = 1000
  }

  ws.onmessage = (event) => {
    try {
      const msg = JSON.parse(event.data)
      if (msg.type === 'session-state-snapshot' || msg.type === 'session-state-patch' || msg.type === 'terminal-registry-change') {
        store.handleMessage(msg)
      }
      // Ignore other message types (terminal output, legacy broadcasts, etc.)
    } catch {
      // Non-JSON or malformed — ignore
    }
  }

  ws.onclose = () => {
    console.log('[SessionStateWS] Disconnected, reconnecting in', reconnectDelay, 'ms')
    store.setConnected(false)
    ws = null
    scheduleReconnect()
  }

  ws.onerror = () => {
    // onclose will fire after onerror
  }
}

function scheduleReconnect() {
  if (reconnectTimer) clearTimeout(reconnectTimer)
  reconnectTimer = setTimeout(() => {
    reconnectTimer = null
    connect()
    // Exponential backoff
    reconnectDelay = Math.min(reconnectDelay * 1.5, MAX_RECONNECT_DELAY)
  }, reconnectDelay)
}

/** Initialize the session state WebSocket. Call once on app mount. */
export function initSessionStateWS() {
  if (ws) return // Already connected
  connect()
}

/** Disconnect and stop reconnecting. */
export function destroySessionStateWS() {
  if (reconnectTimer) {
    clearTimeout(reconnectTimer)
    reconnectTimer = null
  }
  if (ws) {
    ws.onclose = null // Prevent reconnect
    ws.close()
    ws = null
  }
  useSessionState().setConnected(false)
}
