// composables/useWebSocket.ts
import { ref, computed, onUnmounted } from 'vue'

export interface WebSocketConfig {
  url: string
  clientId: string
  onMessage?: (data: any) => void
  onOpen?: () => void
  onClose?: () => void
  onError?: (error: Event) => void
  reconnectInterval?: number
  maxReconnectAttempts?: number
}

export interface WebSocketMessage {
  to_client: string
  data: any
}

export const useWebSocket = (config: WebSocketConfig) => {
  const ws = ref<WebSocket | null>(null)
  const isConnected = ref(false)
  const reconnectAttempts = ref(0)
  const reconnectTimer = ref<NodeJS.Timeout | null>(null)

  const wsUrl = computed(() => {
    const url = new URL(config.url)
    url.searchParams.set('client_id', config.clientId)
    return url.toString()
  })

  const connect = () => {
    try {
      // Close existing connection if any
      if (ws.value && ws.value.readyState !== WebSocket.CLOSED) {
        ws.value.close()
      }

      ws.value = new WebSocket(wsUrl.value)

      ws.value.onopen = () => {
        console.log('WebSocket connected:', config.clientId)
        isConnected.value = true
        reconnectAttempts.value = 0
        config.onOpen?.()
      }

      ws.value.onmessage = (event) => {
        try {
          const data = JSON.parse(event.data)
          config.onMessage?.(data)
        } catch (error) {
          console.error('Error parsing WebSocket message:', error)
        }
      }

      ws.value.onclose = () => {
        console.log('WebSocket closed:', config.clientId)
        isConnected.value = false
        config.onClose?.()

        // Attempt to reconnect
        if (reconnectAttempts.value < (config.maxReconnectAttempts || 5)) {
          reconnectAttempts.value++
          const interval = config.reconnectInterval || 3000
          reconnectTimer.value = setTimeout(() => {
            console.log(`Reconnecting... Attempt ${reconnectAttempts.value}`)
            connect()
          }, interval)
        } else {
          console.error('Max reconnection attempts reached')
        }
      }

      ws.value.onerror = (error) => {
        console.error('WebSocket error:', error)
        config.onError?.(error)
      }
    } catch (error) {
      console.error('Error creating WebSocket:', error)
      config.onError?.(error as Event)
    }
  }

  const disconnect = () => {
    if (reconnectTimer.value) {
      clearTimeout(reconnectTimer.value)
      reconnectTimer.value = null
    }
    if (ws.value) {
      ws.value.close()
      ws.value = null
    }
    isConnected.value = false
  }

  const sendMessage = (message: any) => {
    if (ws.value && ws.value.readyState === WebSocket.OPEN) {
      ws.value.send(JSON.stringify(message))
      return true
    }
    console.warn('WebSocket is not connected')
    return false
  }

  // Send data via POST to WebSocket server
  const sendViaPost = async (message: WebSocketMessage) => {
    try {
      // Extract base URL from WebSocket URL (convert ws:// to http:// or wss:// to https://)
      let baseUrl = config.url
      if (baseUrl.startsWith('ws://')) {
        baseUrl = baseUrl.replace('ws://', 'http://')
      } else if (baseUrl.startsWith('wss://')) {
        baseUrl = baseUrl.replace('wss://', 'https://')
      }
      
      // Remove query parameters and ensure we have the correct POST endpoint
      const urlObj = new URL(baseUrl)
      const postUrl = `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}`

      console.log('📡 POST URL:', postUrl)
      console.log('📦 POST Body:', JSON.stringify(message, null, 2))

      const response = await fetch(postUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(message),
      })

      console.log('📥 POST Response status:', response.status, response.statusText)

      if (!response.ok) {
        const errorText = await response.text().catch(() => 'Unknown error')
        console.error('❌ POST Error response:', errorText)
        throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`)
      }

      const result = await response.json().catch(() => {
        console.log('ℹ️ Response is not JSON, assuming success')
        return { success: true }
      })
      
      console.log('✅ POST Response data:', result)
      return result
    } catch (error) {
      console.error('❌ Error sending message via POST:', error)
      throw error
    }
  }

  onUnmounted(() => {
    disconnect()
  })

  return {
    ws: computed(() => ws.value),
    isConnected: computed(() => isConnected.value),
    connect,
    disconnect,
    sendMessage,
    sendViaPost,
    reconnectAttempts: computed(() => reconnectAttempts.value),
  }
}

