import { connectionStatus } from '@/stores/connection-status'

class BackendBridge {
  private static instance: BackendBridge
  private readonly url: string = 'http://localhost:8000/action/ws'
  private socket: WebSocket | null = null
  private timeout: number | null = null

  private reconnectAttempts = 0
  private readonly maxAttempts = 10
  private readonly baseDelay = 500 // 0.5 seconds

  private constructor() {
    this.connect()
  }

  public static getInstance(): BackendBridge {
    if (!BackendBridge.instance) {
      BackendBridge.instance = new BackendBridge()
    }
    return this.instance
  }

  public manualConnect() {
    if (this.timeout) clearTimeout(this.timeout)
    this.connect()
  }

  private connect(): void {
    console.log(`Connecting to ${this.url}...`)
    if (this.socket) {
      connectionStatus().backendConnected = false
      this.socket.onclose = null
      this.socket.close()
    }
    this.socket = new WebSocket(this.url)

    this.socket.onopen = () => {
      connectionStatus().backendConnected = true
      console.log('Connected successfully!')
      this.reconnectAttempts = 0
    }

    this.socket.onclose = (event) => {
      connectionStatus().backendConnected = false
      console.warn('Socket closed:', event)
      this.handleReconnect()
    }

    this.socket.onerror = (error) => {
      console.error('Socket error:', error)
    }
  }

  // Backoff algorithm
  private handleReconnect(): void {
    if (this.reconnectAttempts < this.maxAttempts) {
      this.reconnectAttempts++

      const delay = this.baseDelay * Math.pow(2, this.reconnectAttempts - 1)

      console.log(
        `Retrying in ${delay}ms... (Attempt ${this.reconnectAttempts}/${this.maxAttempts})`,
      )

      this.timeout = setTimeout(() => {
        this.timeout = null
        console.log(`Starting attempt [${this.reconnectAttempts}/${this.maxAttempts}]`)
        this.connect()
      }, delay)
    } else {
      console.error('Max reconnection attempts reached. Please check your connection.')
    }
  }
}

const rosBackend = BackendBridge.getInstance()

export { rosBackend }

export type { BackendBridge }
