type MessageHandler = (msg: StreamMessage) => void

interface StreamMessage {
  type: 'output' | 'error' | 'status' | 'waiting_input' | 'complete'
  session_id: string
  data: string
  timestamp: string
}

class TerminalWsService {
  private ws: WebSocket | null = null
  private sessionId: string | null = null
  private handlers: MessageHandler[] = []
  private reconnectAttempts = 0
  private maxReconnectAttempts = 5

  async connect(provider: string): Promise<string> {
    // 创建会话
    const response = await fetch('/api/code-commander/sessions', {
      method: 'POST',
      body: JSON.stringify({ provider }),
    })
    const { session_id } = await response.json()
    
    // 建立 WebSocket
    this.ws = new WebSocket(`ws://localhost:8000/ws/terminal/${session_id}`)
    
    this.ws.onmessage = (event) => {
      const msg: StreamMessage = JSON.parse(event.data)
      this.handlers.forEach((h) => h(msg))
    }
    
    this.ws.onclose = () => {
      this.attemptReconnect()
    }
    
    this.sessionId = session_id
    return session_id
  }

  async sendTask(sessionId: string, prompt: string) {
    await fetch(`/api/code-commander/sessions/${sessionId}/task`, {
      method: 'POST',
      body: JSON.stringify({ prompt }),
    })
  }

  sendInput(sessionId: string, input: string) {
    this.ws?.send(JSON.stringify({ type: 'input', data: input }))
  }

  onMessage(handler: MessageHandler) {
    this.handlers.push(handler)
  }

  removeHandler(handler: MessageHandler) {
    this.handlers = this.handlers.filter((h) => h !== handler)
  }

  async disconnect(sessionId: string) {
    await fetch(`/api/code-commander/sessions/${sessionId}`, {
      method: 'DELETE',
    })
    this.ws?.close()
    this.ws = null
    this.sessionId = null
  }

  private async attemptReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      return
    }
    this.reconnectAttempts++
    await new Promise((r) => setTimeout(r, 1000 * this.reconnectAttempts))
    // 重新连接
  }
}

export const terminalWsService = new TerminalWsService()
