import { ref, onMounted, onUnmounted } from 'vue'
import notificationService from './notificationService'

interface WebSocketMessage {
  type: 'NOTIFICATION' | 'APPROVAL_UPDATE' | 'PROCUREMENT_UPDATE' | 'SYSTEM' | 'EQUIPMENT_STATUS_UPDATE' | 'HEARTBEAT' | 'EQUIPMENT_BORROW_UPDATE' | 'EQUIPMENT_RETURN_UPDATE' | 'EQUIPMENT_MAINTENANCE_UPDATE' | 'EQUIPMENT_ALERT' | 'WORKFLOW_UPDATE'
  data: any
  timestamp: number
  messageId?: string
}

class WebSocketService {
  private ws: WebSocket | null = null
  private reconnectAttempts = 0
  private maxReconnectAttempts = 5
  private reconnectInterval = 3000 // 3秒
  private heartbeatInterval: NodeJS.Timeout | null = null
  private isConnected = ref(false)
  private isConnecting = ref(false)
  
  // 连接状态
  public readonly connected = this.isConnected
  public readonly connecting = this.isConnecting
  
  // 连接配置
  private wsUrl = import.meta.env.VITE_API_WS_URL || 'ws://localhost:8888/websocket'
  private token = localStorage.getItem('token') || ''
  
  // 事件监听器
  private eventListeners: Map<string, Function[]> = new Map()
  
  // 消息队列 - 用于离线时缓存消息
  private messageQueue: WebSocketMessage[] = []
  private maxQueueSize = 100
  
  // 消息去重 - 避免重复处理
  private processedMessages = new Set<string>()
  private maxProcessedMessages = 1000
  
  constructor() {
    this.setupEventListeners()
    this.loadMessageQueue()
  }
  
  // 连接WebSocket
  public connect() {
    if (this.isConnecting.value || this.isConnected.value) {
      return
    }
    
    this.isConnecting.value = true
    
    try {
      // 构建WebSocket URL，包含认证token
      const url = `${this.wsUrl}?token=${encodeURIComponent(this.token)}`
      this.ws = new WebSocket(url)
      
      this.ws.onopen = this.handleOpen.bind(this)
      this.ws.onmessage = this.handleMessage.bind(this)
      this.ws.onclose = this.handleClose.bind(this)
      this.ws.onerror = this.handleError.bind(this)
      
    } catch (error) {
      console.error('WebSocket连接失败:', error)
      this.isConnecting.value = false
      this.scheduleReconnect()
    }
  }
  
  // 断开连接
  public disconnect() {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval)
      this.heartbeatInterval = null
    }
    
    if (this.ws) {
      this.ws.close()
      this.ws = null
    }
    
    this.isConnected.value = false
    this.isConnecting.value = false
  }
  
  // 发送消息
  public send(message: any) {
    if (this.ws && this.isConnected.value) {
      try {
        this.ws.send(JSON.stringify(message))
      } catch (error) {
        console.error('发送WebSocket消息失败:', error)
        // 发送失败时，将消息加入队列
        this.addToMessageQueue(message)
      }
    } else {
      console.warn('WebSocket未连接，将消息加入队列')
      this.addToMessageQueue(message)
    }
  }
  
  // 发送心跳
  public sendHeartbeat() {
    this.send({
      type: 'HEARTBEAT',
      data: { timestamp: Date.now() },
      timestamp: Date.now()
    })
  }
  
  // 处理连接打开
  private handleOpen() {
    console.log('WebSocket连接已建立')
    this.isConnected.value = true
    this.isConnecting.value = false
    this.reconnectAttempts = 0
    
    // 启动心跳
    this.startHeartbeat()
    
    // 发送认证消息
    this.send({
      type: 'AUTH',
      data: { token: this.token },
      timestamp: Date.now()
    })
    
    // 处理离线期间的消息队列
    this.processMessageQueue()
    
    // 触发连接事件
    this.emit('connected', null)
  }
  
  // 处理消息接收
  private handleMessage(event: MessageEvent) {
    try {
      const message: WebSocketMessage = JSON.parse(event.data)
      this.processMessage(message)
    } catch (error) {
      console.error('解析WebSocket消息失败:', error)
    }
  }
  
  // 处理连接关闭
  private handleClose(event: CloseEvent) {
    console.log('WebSocket连接已关闭:', event.code, event.reason)
    this.isConnected.value = false
    this.isConnecting.value = false
    
    // 停止心跳
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval)
      this.heartbeatInterval = null
    }
    
    // 触发断开连接事件
    this.emit('disconnected', { code: event.code, reason: event.reason })
    
    // 如果不是主动关闭，尝试重连
    if (event.code !== 1000) {
      this.scheduleReconnect()
    }
  }
  
  // 处理连接错误
  private handleError(error: Event) {
    console.error('WebSocket连接错误:', error)
    this.isConnecting.value = false
    
    // 触发错误事件
    this.emit('error', error)
    
    // 尝试重连
    this.scheduleReconnect()
  }
  
  // 处理接收到的消息
  private processMessage(message: WebSocketMessage) {
    console.log('收到WebSocket消息:', message)
    
    // 消息去重检查
    if (message.messageId && this.processedMessages.has(message.messageId)) {
      console.log('消息已处理，跳过:', message.messageId)
      return
    }
    
            // 添加到已处理消息集合
        if (message.messageId) {
          this.processedMessages.add(message.messageId)
          // 限制已处理消息数量
          if (this.processedMessages.size > this.maxProcessedMessages) {
            const firstKey = this.processedMessages.keys().next().value
            if (firstKey) {
              this.processedMessages.delete(firstKey)
            }
          }
        }
    
    switch (message.type) {
      case 'NOTIFICATION':
        this.handleNotificationMessage(message.data)
        break
        
      case 'APPROVAL_UPDATE':
        this.handleApprovalUpdateMessage(message.data)
        break
        
      case 'PROCUREMENT_UPDATE':
        this.handleProcurementUpdateMessage(message.data)
        break
        
      case 'EQUIPMENT_STATUS_UPDATE':
        this.handleEquipmentStatusUpdateMessage(message.data)
        break
        
      case 'EQUIPMENT_BORROW_UPDATE':
        this.handleEquipmentBorrowUpdateMessage(message.data)
        break
        
      case 'EQUIPMENT_RETURN_UPDATE':
        this.handleEquipmentReturnUpdateMessage(message.data)
        break
        
      case 'EQUIPMENT_MAINTENANCE_UPDATE':
        this.handleEquipmentMaintenanceUpdateMessage(message.data)
        break
        
      case 'EQUIPMENT_ALERT':
        this.handleEquipmentAlertMessage(message.data)
        break
        
      case 'WORKFLOW_UPDATE':
        this.handleWorkflowUpdateMessage(message.data)
        break
        
      case 'SYSTEM':
        this.handleSystemMessage(message.data)
        break
        
      case 'HEARTBEAT':
        // 心跳响应，不需要特殊处理
        break
        
      default:
        console.warn('未知的WebSocket消息类型:', message.type)
    }
    
    // 触发消息接收事件
    this.emit('message', message)
    
    // 保存消息到本地存储
    this.saveMessageToStorage(message)
  }
  
  // 处理通知消息
  private handleNotificationMessage(data: any) {
    if (data.notification) {
      notificationService.addNotification({
        type: data.notification.type || 'SYSTEM',
        title: data.notification.title || '新通知',
        content: data.notification.content || '',
        priority: data.notification.priority || 'NORMAL',
        category: data.notification.category,
        targetUrl: data.notification.targetUrl,
        metadata: data.notification.metadata
      })
    }
  }
  
  // 处理审批更新消息
  private handleApprovalUpdateMessage(data: any) {
    if (data.approval) {
      const approval = data.approval
      
      // 根据审批状态添加相应通知
      if (approval.status === 'APPROVED') {
        notificationService.addApprovalNotification(
          approval.equipmentName,
          'APPROVED',
          approval.approverName || '审批人'
        )
        
        // 触发审批状态更新事件
        this.emit('approvalStatusChanged', {
          type: 'APPROVED',
          approvalId: approval.approvalId,
          equipmentId: approval.equipmentId,
          status: approval.status
        })
      } else if (approval.status === 'REJECTED') {
        notificationService.addApprovalNotification(
          approval.equipmentName,
          'REJECTED',
          approval.approverName || '审批人'
        )
        
        // 触发审批状态更新事件
        this.emit('approvalStatusChanged', {
          type: 'REJECTED',
          approvalId: approval.approvalId,
          equipmentId: approval.equipmentId,
          status: approval.status
        })
      } else if (approval.status === 'SUBMITTED') {
        // 新增待审批通知
        notificationService.addNotification({
          type: 'PENDING',
          title: '新的审批申请',
          content: `收到来自 ${approval.applicantName} 的${approval.businessType || '设备'}申请：${approval.equipmentName}`,
          targetUrl: '/asset-management/device-management/approval',
          priority: 'HIGH',
          category: '审批申请',
          metadata: {
            approvalId: approval.approvalId,
            equipmentName: approval.equipmentName,
            applicantName: approval.applicantName,
            businessType: approval.businessType,
            timestamp: Date.now()
          }
        })
        
        // 触发新审批申请事件
        this.emit('newApprovalRequest', approval)
      }
    }
  }
  
  // 处理采购更新消息
  private handleProcurementUpdateMessage(data: any) {
    if (data.procurement) {
      const procurement = data.procurement
      
      if (procurement.status === 'SUBMITTED') {
        notificationService.addProcurementNotification(
          procurement.equipmentName,
          procurement.applicantName || '申请人'
        )
        
        // 触发采购状态更新事件
        this.emit('procurementStatusChanged', {
          type: 'SUBMITTED',
          procurementId: procurement.procurementId,
          equipmentId: procurement.equipmentId,
          status: procurement.status
        })
      } else if (procurement.status === 'APPROVED') {
        // 采购申请被批准
        notificationService.addNotification({
          type: 'PROCUREMENT',
          title: '采购申请已批准',
          content: `您的设备采购申请"${procurement.equipmentName}"已获得批准`,
          targetUrl: '/asset-management/device-management/procurement',
          priority: 'NORMAL',
          category: '采购审批',
          metadata: {
            equipmentName: procurement.equipmentName,
            status: procurement.status,
            timestamp: Date.now()
          }
        })
        
        // 触发采购状态更新事件
        this.emit('procurementStatusChanged', {
          type: 'APPROVED',
          procurementId: procurement.procurementId,
          equipmentId: procurement.equipmentId,
          status: procurement.status
        })
      }
    }
  }
  
  // 处理设备状态更新消息
  private handleEquipmentStatusUpdateMessage(data: any) {
    if (data.equipment) {
      const equipment = data.equipment
      
      // 触发设备状态更新事件
      this.emit('equipmentStatusChanged', {
        equipmentId: equipment.equipmentId,
        oldStatus: equipment.oldStatus,
        newStatus: equipment.newStatus,
        updateTime: equipment.updateTime
      })
      
      // 如果状态变化涉及采购，添加相应通知
      if (equipment.statusChangeType === 'PROCUREMENT') {
        notificationService.addNotification({
          type: 'PROCUREMENT',
          title: '设备采购状态更新',
          content: `设备"${equipment.equipmentName}"的采购状态已更新为：${equipment.newStatus}`,
          targetUrl: '/asset-management/device-management/procurement',
          priority: 'NORMAL',
          category: '设备状态',
          metadata: {
            equipmentId: equipment.equipmentId,
            equipmentName: equipment.equipmentName,
            oldStatus: equipment.oldStatus,
            newStatus: equipment.newStatus,
            timestamp: Date.now()
          }
        })
      }
    }
  }
  
  // 处理设备借用更新消息
  private handleEquipmentBorrowUpdateMessage(data: any) {
    if (data.borrow) {
      const borrow = data.borrow
      
      // 触发设备借用状态更新事件
      this.emit('equipmentBorrowChanged', {
        equipmentId: borrow.equipmentId,
        borrowId: borrow.borrowId,
        oldStatus: borrow.oldStatus,
        newStatus: borrow.newStatus,
        updateTime: borrow.updateTime
      })
      
      // 添加借用状态更新通知
      notificationService.addNotification({
        type: 'EQUIPMENT_BORROW',
        title: '设备借用状态更新',
        content: `设备"${borrow.equipmentName}"的借用状态已更新为：${borrow.newStatus}`,
        targetUrl: '/asset-management/device-management/device-center',
        priority: 'NORMAL',
        category: '设备借用',
        metadata: {
          equipmentId: borrow.equipmentId,
          equipmentName: borrow.equipmentName,
          borrowId: borrow.borrowId,
          oldStatus: borrow.oldStatus,
          newStatus: borrow.newStatus,
          timestamp: Date.now()
        }
      })
    }
  }
  
  // 处理设备归还更新消息
  private handleEquipmentReturnUpdateMessage(data: any) {
    if (data.return) {
      const returnData = data.return
      
      // 触发设备归还状态更新事件
      this.emit('equipmentReturnChanged', {
        equipmentId: returnData.equipmentId,
        returnId: returnData.returnId,
        oldStatus: returnData.oldStatus,
        newStatus: returnData.newStatus,
        updateTime: returnData.updateTime
      })
      
      // 添加归还状态更新通知
      notificationService.addNotification({
        type: 'EQUIPMENT_RETURN',
        title: '设备归还状态更新',
        content: `设备"${returnData.equipmentName}"的归还状态已更新为：${returnData.newStatus}`,
        targetUrl: '/asset-management/device-management/device-center',
        priority: 'NORMAL',
        category: '设备归还',
        metadata: {
          equipmentId: returnData.equipmentId,
          equipmentName: returnData.equipmentName,
          returnId: returnData.returnId,
          oldStatus: returnData.oldStatus,
          newStatus: returnData.newStatus,
          timestamp: Date.now()
        }
      })
    }
  }
  
  // 处理设备维护更新消息
  private handleEquipmentMaintenanceUpdateMessage(data: any) {
    if (data.maintenance) {
      const maintenance = data.maintenance
      
      // 触发设备维护状态更新事件
      this.emit('equipmentMaintenanceChanged', {
        equipmentId: maintenance.equipmentId,
        maintenanceId: maintenance.maintenanceId,
        oldStatus: maintenance.oldStatus,
        newStatus: maintenance.newStatus,
        updateTime: maintenance.updateTime
      })
      
      // 添加维护状态更新通知
      notificationService.addNotification({
        type: 'EQUIPMENT_MAINTENANCE',
        title: '设备维护状态更新',
        content: `设备"${maintenance.equipmentName}"的维护状态已更新为：${maintenance.newStatus}`,
        targetUrl: '/asset-management/device-management/device-center',
        priority: 'NORMAL',
        category: '设备维护',
        metadata: {
          equipmentId: maintenance.equipmentId,
          equipmentName: maintenance.equipmentName,
          maintenanceId: maintenance.maintenanceId,
          oldStatus: maintenance.oldStatus,
          newStatus: maintenance.newStatus,
          timestamp: Date.now()
        }
      })
    }
  }
  
  // 处理设备告警消息
  private handleEquipmentAlertMessage(data: any) {
    if (data.alert) {
      const alert = data.alert
      
      // 触发设备告警事件
      this.emit('equipmentAlert', {
        equipmentId: alert.equipmentId,
        alertId: alert.alertId,
        alertType: alert.alertType,
        alertLevel: alert.alertLevel,
        message: alert.message,
        timestamp: alert.timestamp
      })
      
      // 添加设备告警通知
      notificationService.addNotification({
        type: 'EQUIPMENT_ALERT',
        title: `设备告警 - ${alert.alertType}`,
        content: `设备"${alert.equipmentName}"发生告警：${alert.message}`,
        targetUrl: '/asset-management/device-management/device-center',
        priority: alert.alertLevel === 'CRITICAL' ? 'URGENT' : 'HIGH',
        category: '设备告警',
        actionRequired: true,
        metadata: {
          equipmentId: alert.equipmentId,
          equipmentName: alert.equipmentName,
          alertId: alert.alertId,
          alertType: alert.alertType,
          alertLevel: alert.alertLevel,
          message: alert.message,
          timestamp: Date.now()
        }
      })
    }
  }
  
  // 处理工作流更新消息
  private handleWorkflowUpdateMessage(data: any) {
    if (data.workflow) {
      const workflow = data.workflow
      
      // 触发工作流状态更新事件
      this.emit('workflowStatusChanged', {
        workflowId: workflow.workflowId,
        oldStatus: workflow.oldStatus,
        newStatus: workflow.newStatus,
        currentNode: workflow.currentNode,
        updateTime: workflow.updateTime
      })
      
      // 添加工作流状态更新通知
      notificationService.addNotification({
        type: 'WORKFLOW',
        title: '工作流状态更新',
        content: `工作流"${workflow.workflowName}"状态已更新为：${workflow.newStatus}`,
        targetUrl: '/asset-management/device-management/approval',
        priority: 'NORMAL',
        category: '工作流',
        metadata: {
          workflowId: workflow.workflowId,
          workflowName: workflow.workflowName,
          oldStatus: workflow.oldStatus,
          newStatus: workflow.newStatus,
          currentNode: workflow.currentNode,
          timestamp: Date.now()
        }
      })
    }
  }
  
  // 处理系统消息
  private handleSystemMessage(data: any) {
    if (data.system) {
      const system = data.system
      
      notificationService.addSystemNotification(
        system.title || '系统通知',
        system.content || '',
        system.priority || 'NORMAL'
      )
    }
  }
  
  // 启动心跳
  private startHeartbeat() {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval)
    }
    
    this.heartbeatInterval = setInterval(() => {
      if (this.isConnected.value) {
        this.sendHeartbeat()
      }
    }, 30000) // 30秒发送一次心跳
  }
  
  // 安排重连
  private scheduleReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('WebSocket重连次数已达上限，停止重连')
      return
    }
    
    this.reconnectAttempts++
    console.log(`WebSocket将在 ${this.reconnectInterval / 1000} 秒后尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`)
    
    setTimeout(() => {
      this.connect()
    }, this.reconnectInterval)
    
    // 递增重连间隔
    this.reconnectInterval = Math.min(this.reconnectInterval * 1.5, 30000)
  }
  
  // 消息队列管理
  private addToMessageQueue(message: any) {
    this.messageQueue.push(message)
    if (this.messageQueue.length > this.maxQueueSize) {
      this.messageQueue.shift() // 移除最旧的消息
    }
    this.saveMessageQueue()
  }
  
  private processMessageQueue() {
    if (this.messageQueue.length > 0) {
      console.log(`处理离线期间的消息队列，共 ${this.messageQueue.length} 条消息`)
      const messages = [...this.messageQueue]
      this.messageQueue = []
      
      messages.forEach(message => {
        this.processMessage(message)
      })
      
      this.saveMessageQueue()
    }
  }
  
  private saveMessageQueue() {
    try {
      localStorage.setItem('websocket_message_queue', JSON.stringify(this.messageQueue))
    } catch (error) {
      console.error('保存消息队列失败:', error)
    }
  }
  
  private loadMessageQueue() {
    try {
      const stored = localStorage.getItem('websocket_message_queue')
      if (stored) {
        this.messageQueue = JSON.parse(stored)
      }
    } catch (error) {
      console.error('加载消息队列失败:', error)
    }
  }
  
  // 消息存储管理
  private saveMessageToStorage(message: WebSocketMessage) {
    try {
      const messages = this.getStoredMessages()
      messages.unshift(message)
      
      // 限制存储的消息数量
      if (messages.length > 200) {
        messages.splice(200)
      }
      
      localStorage.setItem('websocket_messages', JSON.stringify(messages))
    } catch (error) {
      console.error('保存消息到本地存储失败:', error)
    }
  }
  
  private getStoredMessages(): WebSocketMessage[] {
    try {
      const stored = localStorage.getItem('websocket_messages')
      return stored ? JSON.parse(stored) : []
    } catch (error) {
      console.error('获取存储的消息失败:', error)
      return []
    }
  }
  
  // 设置事件监听器
  private setupEventListeners() {
    // 监听token变化，重新连接
    window.addEventListener('storage', (event) => {
      if (event.key === 'token' && event.newValue !== this.token) {
        this.token = event.newValue || ''
        if (this.isConnected.value) {
          this.disconnect()
          this.connect()
        }
      }
    })
  }
  
  // 事件系统
  public on(event: string, callback: Function) {
    if (!this.eventListeners.has(event)) {
      this.eventListeners.set(event, [])
    }
    this.eventListeners.get(event)!.push(callback)
  }
  
  public off(event: string, callback: Function) {
    const listeners = this.eventListeners.get(event)
    if (listeners) {
      const index = listeners.indexOf(callback)
      if (index > -1) {
        listeners.splice(index, 1)
      }
    }
  }
  
  private emit(event: string, data: any) {
    const listeners = this.eventListeners.get(event)
    if (listeners) {
      listeners.forEach(callback => {
        try {
          callback(data)
        } catch (error) {
          console.error('WebSocket事件回调执行失败:', error)
        }
      })
    }
  }
  
  // 获取连接状态
  public getStatus() {
    return {
      connected: this.isConnected.value,
      connecting: this.isConnecting.value,
      reconnectAttempts: this.reconnectAttempts,
      maxReconnectAttempts: this.maxReconnectAttempts,
      messageQueueSize: this.messageQueue.length,
      processedMessagesCount: this.processedMessages.size
    }
  }
  
  // 更新认证token
  public updateToken(newToken: string) {
    this.token = newToken
    if (this.isConnected.value) {
      // 重新认证
      this.send({
        type: 'AUTH',
        data: { token: this.token },
        timestamp: Date.now()
      })
    }
  }
  
  // 获取存储的消息
  public getMessages() {
    return this.getStoredMessages()
  }
  
  // 清空存储的消息
  public clearMessages() {
    try {
      localStorage.removeItem('websocket_messages')
      localStorage.removeItem('websocket_message_queue')
      this.messageQueue = []
      this.processedMessages.clear()
    } catch (error) {
      console.error('清空消息失败:', error)
    }
  }
}

// 创建单例实例
const websocketService = new WebSocketService()

// 自动连接
websocketService.connect()

export default websocketService
