import { Client, IMessage } from '@stomp/stompjs'
import SockJS from 'sockjs-client'
import { envConfig } from '@/config/env'

// WebSocket消息类型
export interface WebSocketMessage {
  messageId?: string
  conversationId?: string
  type: 'TEXT' | 'TYPING' | 'SYSTEM' | 'ERROR' | 'HEARTBEAT' | 'CONNECTION' | 'AI_THINKING'
  content: string
  senderId: string
  senderType: 'USER' | 'GUEST' | 'AI' | 'SYSTEM'
  status?: 'SENDING' | 'SENT' | 'DELIVERED' | 'READ' | 'FAILED'
  createTime?: string
  timestamp?: number
  data?: any
}

// 聊天请求类型 - 完全匹配后端ChatRequest
export interface ChatRequest {
  content: string
  senderId: string
  senderType: 'USER' | 'GUEST' | 'AI' | 'SYSTEM'
  messageType: 'TEXT' | 'IMAGE' | 'FILE' | 'SYSTEM' | 'HEARTBEAT'
  conversationId?: string
  timestamp?: number
}

// 连接状态
export type ConnectionStatus = 'CONNECTING' | 'CONNECTED' | 'DISCONNECTED' | 'ERROR'

// 事件回调类型
export interface WebSocketCallbacks {
  onMessage?: (message: WebSocketMessage) => void
  onConnect?: () => void
  onDisconnect?: () => void
  onError?: (error: any) => void
  onStatusChange?: (status: ConnectionStatus) => void
}

/**
 * STOMP WebSocket服务类
 * 使用STOMP协议与后端Spring WebSocket通信
 */
export class StompWebSocketService {
  private client: Client | null = null
  private callbacks: WebSocketCallbacks = {}
  private status: ConnectionStatus = 'DISCONNECTED'
  private reconnectAttempts = 0
  private maxReconnectAttempts = 5
  private reconnectInterval = 3000
  private userId: string | null = null
  private conversationId: string | null = null

  constructor() {
    // 构建WebSocket URL
    const wsUrl = `${envConfig.apiBaseUrl}/ws/chat`
    console.log('STOMP WebSocket URL:', wsUrl)
  }

  /**
   * 连接WebSocket
   */
  connect(userId?: string, callbacks?: WebSocketCallbacks): Promise<void> {
    return new Promise((resolve, reject) => {
      try {
        this.callbacks = { ...callbacks }
        
        // 设置用户ID和类型
        if (userId) {
          this.userId = userId
          console.log('🔌 使用登录用户ID:', userId)
        } else {
          this.userId = `guest_${Date.now()}`
          console.log('🔌 使用访客ID:', this.userId)
        }
        
        this.setStatus('CONNECTING')

        // 创建STOMP客户端
        this.client = new Client({
          webSocketFactory: () => {
            const wsUrl = `${envConfig.apiBaseUrl}/ws/chat`
            return new SockJS(wsUrl)
          },
          
          // 连接头信息
          connectHeaders: this.getConnectHeaders(),
          
          // 调试信息
          debug: (str) => {
            console.log('STOMP Debug:', str)
          },
          
          // 重连配置
          reconnectDelay: this.reconnectInterval,
          heartbeatIncoming: 4000,
          heartbeatOutgoing: 4000,
        })

        // 连接成功回调
        this.client.onConnect = (frame) => {
          console.log('✅ STOMP WebSocket连接成功:', frame)
          this.setStatus('CONNECTED')
          this.reconnectAttempts = 0
          
          // 订阅消息
          this.subscribeToMessages()
          
          // 发送连接消息
          this.sendConnectMessage()
          
          this.callbacks.onConnect?.()
          resolve()
        }

        // 连接错误回调
        this.client.onStompError = (frame) => {
          console.error('❌ STOMP连接错误:', frame)
          this.setStatus('ERROR')
          this.callbacks.onError?.(frame)
          reject(new Error(`STOMP连接错误: ${frame.headers['message']}`))
        }

        // WebSocket错误回调
        this.client.onWebSocketError = (error) => {
          console.error('❌ WebSocket错误:', error)
          this.setStatus('ERROR')
          this.callbacks.onError?.(error)
        }

        // 连接关闭回调
        this.client.onWebSocketClose = (event) => {
          console.log('🔌 WebSocket连接关闭:', event)
          this.setStatus('DISCONNECTED')
          this.callbacks.onDisconnect?.()
          
          // 自动重连
          if (!event.wasClean && this.reconnectAttempts < this.maxReconnectAttempts) {
            this.scheduleReconnect()
          }
        }

        // 激活连接
        this.client.activate()

      } catch (error) {
        console.error('❌ STOMP连接异常:', error)
        this.setStatus('ERROR')
        this.callbacks.onError?.(error)
        reject(error)
      }
    })
  }

  /**
   * 断开连接
   */
  disconnect(): void {
    if (this.client) {
      this.client.deactivate()
      this.client = null
    }
    this.userId = null
    this.conversationId = null
    this.setStatus('DISCONNECTED')
  }

  /**
   * 发送聊天消息
   */
  sendChatMessage(content: string, conversationId?: string): void {
    if (!this.client || !this.client.connected) {
      const error = new Error('STOMP客户端未连接，无法发送消息')
      console.error('STOMP未连接')
      this.callbacks.onError?.({ userMessage: '连接已断开，请等待重连后再试', originalError: error })
      return
    }

    if (!content.trim()) {
      const error = new Error('消息内容不能为空')
      this.callbacks.onError?.({ userMessage: '消息内容不能为空', originalError: error })
      return
    }

    // 判断用户类型
    const isGuest = !this.userId || this.userId.startsWith('guest_')
    const senderType = isGuest ? 'GUEST' : 'USER'
    
    console.log('📤 发送STOMP聊天消息，用户信息:', {
      userId: this.userId,
      senderType,
      isGuest,
      content: content.trim()
    })

    // 创建聊天请求 - 匹配后端ChatRequest格式
    const chatRequest: ChatRequest = {
      content: content.trim(),
      senderId: this.userId!,
      senderType,
      messageType: 'TEXT',
      conversationId: conversationId || this.conversationId || undefined,
      timestamp: Date.now()
    }

    console.log('📤 准备发送的聊天请求:', chatRequest)

    try {
      // 发送到后端的/app/chat/send端点（对应 @MessageMapping("/chat") + @MessageMapping("/send")）
      this.client.publish({
        destination: '/app/chat/send',
        body: JSON.stringify(chatRequest)
      })
      console.log('✅ STOMP聊天消息发送成功:', chatRequest)
    } catch (error) {
      console.error('❌ STOMP消息发送失败:', error)
      this.callbacks.onError?.({
        userMessage: '消息发送失败，请重试',
        originalError: error
      })
    }
  }

  /**
   * 设置会话ID
   */
  setConversationId(conversationId: string): void {
    this.conversationId = conversationId
    console.log('设置会话ID:', conversationId)
  }

  /**
   * 获取连接状态
   */
  getStatus(): ConnectionStatus {
    return this.status
  }

  /**
   * 是否已连接
   */
  isConnected(): boolean {
    return this.status === 'CONNECTED' && this.client?.connected === true
  }

  /**
   * 获取连接头信息
   */
  private getConnectHeaders(): Record<string, string> {
    const headers: Record<string, string> = {}

    // 添加用户ID
    if (this.userId) {
      headers['X-User-Id'] = this.userId
    }

    // 添加JWT token - 修复：使用正确的localStorage key
    const token = localStorage.getItem('access_token')
    if (token) {
      headers['Authorization'] = `Bearer ${token}`
      console.log('🔐 添加Authorization头到STOMP连接，token预览:', token.substring(0, 20) + '...')
    } else {
      console.warn('🔐 未找到access_token，WebSocket将以访客身份连接')
    }

    return headers
  }

  /**
   * 订阅消息
   */
  private subscribeToMessages(): void {
    if (!this.client?.connected) return

    // 订阅用户私有消息 - 这是主要的消息接收频道
    if (this.userId) {
      const userQueuePath = `/user/${this.userId}/queue/messages`
      console.log('📨 订阅用户私有队列:', userQueuePath)
      
      this.client.subscribe(userQueuePath, (message: IMessage) => {
        this.handleMessage(message)
      })
    }

    // 订阅广播消息（系统通知等）
    this.client.subscribe('/topic/broadcast', (message: IMessage) => {
      this.handleMessage(message)
    })

    // 注释掉会话特定消息订阅，避免重复接收消息
    // 所有消息都通过用户私有队列接收，确保消息不重复
    // if (this.conversationId) {
    //   this.client.subscribe(`/topic/conversation/${this.conversationId}`, (message: IMessage) => {
    //     this.handleMessage(message)
    //   })
    // }
  }

  /**
   * 处理收到的消息
   */
  private handleMessage(message: IMessage): void {
    try {
      const wsMessage: WebSocketMessage = JSON.parse(message.body)
      console.log('📨 收到STOMP消息:', wsMessage)
      this.callbacks.onMessage?.(wsMessage)
    } catch (error) {
      console.error('❌ 解析STOMP消息失败:', error, message.body)
    }
  }

  /**
   * 发送连接消息
   */
  private sendConnectMessage(): void {
    if (!this.client?.connected) return

    const connectRequest = {
      userId: this.userId,
      clientType: 'web',
      clientVersion: '1.0.0',
      timestamp: Date.now()
    }

    try {
      this.client.publish({
        destination: '/app/chat/connect',
        body: JSON.stringify(connectRequest)
      })
      console.log('✅ STOMP连接消息发送成功:', connectRequest)
    } catch (error) {
      console.error('❌ STOMP连接消息发送失败:', error)
    }
  }

  /**
   * 设置连接状态
   */
  private setStatus(status: ConnectionStatus): void {
    this.status = status
    this.callbacks.onStatusChange?.(status)
  }

  /**
   * 安排重连
   */
  private scheduleReconnect(): void {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('达到最大重连次数，停止重连')
      return
    }

    this.reconnectAttempts++
    console.log(`${this.reconnectInterval}ms后尝试第${this.reconnectAttempts}次重连`)

    setTimeout(() => {
      if (this.status !== 'CONNECTED') {
        this.connect(this.userId!, this.callbacks).catch(() => {
          // 重连失败会自动安排下次重连
        })
      }
    }, this.reconnectInterval)

    // 递增重连间隔
    this.reconnectInterval = Math.min(this.reconnectInterval * 1.5, 30000)
  }
}

// 创建STOMP WebSocket服务实例
export const stompWebSocketService = new StompWebSocketService()

export default stompWebSocketService
