/**
 * 消息管理工具
 * 提供消息去重、状态管理、缓存等功能
 */

export interface MessageItem {
  id?: string | number
  _id?: string | number
  message_id?: string | number
  sender_id: string
  sender_name: string
  sender_avatar?: string
  content: any
  msg_type: number
  send_time: string
  _sending?: boolean
  _failed?: boolean
  _local?: boolean // 本地临时消息标记
}

export interface MessageCache {
  messages: Map<string, MessageItem>
  messageOrder: string[] // 保持消息顺序
  lastUpdateTime: number
  maxCacheSize: number
}

export class MessageManager {
  private cache: MessageCache
  private readonly MAX_CACHE_SIZE = 1000 // 最大缓存消息数量
  private readonly CACHE_CLEANUP_THRESHOLD = 1200 // 触发清理的阈值

  constructor(maxCacheSize: number = 1000) {
    this.cache = {
      messages: new Map(),
      messageOrder: [],
      lastUpdateTime: Date.now(),
      maxCacheSize
    }
  }

  /**
   * 获取消息的唯一标识
   */
  getMessageId(message: MessageItem): string {
    // 优先级：message_id > id > _id > 组合键
    if (message.message_id) {
      return String(message.message_id)
    }
    if (message.id) {
      return String(message.id)
    }
    if (message._id) {
      return String(message._id)
    }
    
    // 使用组合键作为后备方案
    const timeKey = new Date(message.send_time).getTime()
    const contentKey = this.getContentHash(message.content)
    return `${message.sender_id}-${timeKey}-${contentKey}`
  }

  /**
   * 获取内容哈希值（简单实现）
   */
  private getContentHash(content: any): string {
    const str = typeof content === 'string' ? content : JSON.stringify(content)
    let hash = 0
    for (let i = 0; i < str.length; i++) {
      const char = str.charCodeAt(i)
      hash = ((hash << 5) - hash) + char
      hash = hash & hash // 转换为32位整数
    }
    return Math.abs(hash).toString(36)
  }

  /**
   * 添加消息到缓存
   */
  addMessage(message: MessageItem): boolean {
    const messageId = this.getMessageId(message)
    
    // 检查是否已存在
    if (this.cache.messages.has(messageId)) {
      // 更新现有消息（可能是状态变化）
      const existingMessage = this.cache.messages.get(messageId)!
      const updatedMessage = { ...existingMessage, ...message }
      this.cache.messages.set(messageId, updatedMessage)
      return false // 表示不是新消息
    }

    // 添加新消息
    this.cache.messages.set(messageId, { ...message })
    this.cache.messageOrder.push(messageId)
    this.cache.lastUpdateTime = Date.now()

    // 检查是否需要清理缓存
    if (this.cache.messageOrder.length > this.CACHE_CLEANUP_THRESHOLD) {
      this.cleanupCache()
    }

    return true // 表示是新消息
  }

  /**
   * 批量添加消息
   */
  addMessages(messages: MessageItem[]): { newMessages: MessageItem[], updatedMessages: MessageItem[] } {
    const newMessages: MessageItem[] = []
    const updatedMessages: MessageItem[] = []

    for (const message of messages) {
      const isNew = this.addMessage(message)
      if (isNew) {
        newMessages.push(message)
      } else {
        updatedMessages.push(message)
      }
    }

    return { newMessages, updatedMessages }
  }

  /**
   * 获取所有消息（按时间排序）
   */
  getAllMessages(): MessageItem[] {
    return this.cache.messageOrder
      .map(id => this.cache.messages.get(id))
      .filter(Boolean) as MessageItem[]
  }

  /**
   * 获取指定范围的消息
   */
  getMessages(start: number = 0, count: number = 50): MessageItem[] {
    const allMessages = this.getAllMessages()
    return allMessages.slice(start, start + count)
  }

  /**
   * 获取最新的N条消息
   */
  getLatestMessages(count: number = 50): MessageItem[] {
    const allMessages = this.getAllMessages()
    return allMessages.slice(-count)
  }

  /**
   * 更新消息状态
   */
  updateMessageStatus(messageId: string, updates: Partial<MessageItem>): boolean {
    const message = this.cache.messages.get(messageId)
    if (!message) {
      return false
    }

    const updatedMessage = { ...message, ...updates }
    this.cache.messages.set(messageId, updatedMessage)
    this.cache.lastUpdateTime = Date.now()
    return true
  }

  /**
   * 标记消息为发送中
   */
  markMessageSending(messageId: string): boolean {
    return this.updateMessageStatus(messageId, { _sending: true, _failed: false })
  }

  /**
   * 标记消息发送成功
   */
  markMessageSent(messageId: string, serverMessage?: Partial<MessageItem>): boolean {
    const updates: Partial<MessageItem> = {
      _sending: false,
      _failed: false,
      _local: false,
      ...serverMessage
    }
    return this.updateMessageStatus(messageId, updates)
  }

  /**
   * 标记消息发送失败
   */
  markMessageFailed(messageId: string): boolean {
    return this.updateMessageStatus(messageId, { _sending: false, _failed: true })
  }

  /**
   * 删除消息
   */
  removeMessage(messageId: string): boolean {
    if (!this.cache.messages.has(messageId)) {
      return false
    }

    this.cache.messages.delete(messageId)
    const index = this.cache.messageOrder.indexOf(messageId)
    if (index > -1) {
      this.cache.messageOrder.splice(index, 1)
    }
    
    this.cache.lastUpdateTime = Date.now()
    return true
  }

  /**
   * 清理缓存（移除最旧的消息）
   */
  private cleanupCache(): void {
    const excessCount = this.cache.messageOrder.length - this.cache.maxCacheSize
    if (excessCount <= 0) {
      return
    }

    // 移除最旧的消息
    const messagesToRemove = this.cache.messageOrder.splice(0, excessCount)
    for (const messageId of messagesToRemove) {
      this.cache.messages.delete(messageId)
    }

    console.log(`清理了 ${excessCount} 条旧消息，当前缓存大小: ${this.cache.messageOrder.length}`)
  }

  /**
   * 清空所有消息
   */
  clear(): void {
    this.cache.messages.clear()
    this.cache.messageOrder = []
    this.cache.lastUpdateTime = Date.now()
  }

  /**
   * 清理旧消息
   */
  cleanup(removeCount: number) {
    if (removeCount <= 0 || removeCount >= this.cache.messageOrder.length) return
    
    // 移除最旧的消息
    const messagesToRemove = this.cache.messageOrder.splice(0, removeCount)
    
    // 从缓存中移除对应的消息
    messagesToRemove.forEach(messageId => {
      this.cache.messages.delete(messageId)
    })
    
    this.cache.lastUpdateTime = Date.now()
    console.log(`MessageManager: 清理了 ${removeCount} 条旧消息`)
  }

  /**
   * 获取缓存统计信息
   */
  getStats() {
    return {
      totalMessages: this.cache.messageOrder.length,
      cacheSize: this.cache.messages.size,
      lastUpdateTime: this.cache.lastUpdateTime,
      maxCacheSize: this.cache.maxCacheSize,
      memoryUsage: this.estimateMemoryUsage()
    }
  }

  /**
   * 估算内存使用量（字节）
   */
  private estimateMemoryUsage(): number {
    let totalSize = 0
    
    for (const message of this.cache.messages.values()) {
      // 粗略估算每个消息对象的大小
      totalSize += JSON.stringify(message).length * 2 // UTF-16编码，每字符2字节
    }
    
    // 加上Map和Array的开销
    totalSize += this.cache.messageOrder.length * 50 // 每个字符串引用约50字节
    
    return totalSize
  }

  /**
   * 导出消息数据（用于持久化）
   */
  export(): { messages: MessageItem[], order: string[], timestamp: number } {
    return {
      messages: Array.from(this.cache.messages.values()),
      order: [...this.cache.messageOrder],
      timestamp: this.cache.lastUpdateTime
    }
  }

  /**
   * 导入消息数据（从持久化恢复）
   */
  import(data: { messages: MessageItem[], order: string[], timestamp: number }): void {
    this.clear()
    
    // 重建缓存
    for (const message of data.messages) {
      const messageId = this.getMessageId(message)
      this.cache.messages.set(messageId, message)
    }
    
    this.cache.messageOrder = [...data.order]
    this.cache.lastUpdateTime = data.timestamp
    
    // 验证数据完整性
    this.validateCache()
  }

  /**
   * 验证缓存数据完整性
   */
  private validateCache(): void {
    // 移除order中不存在的消息ID
    this.cache.messageOrder = this.cache.messageOrder.filter(id => 
      this.cache.messages.has(id)
    )
    
    // 移除messages中不在order中的消息
    for (const messageId of this.cache.messages.keys()) {
      if (!this.cache.messageOrder.includes(messageId)) {
        this.cache.messages.delete(messageId)
      }
    }
  }

  /**
   * 查找消息
   */
  findMessage(predicate: (message: MessageItem) => boolean): MessageItem | undefined {
    for (const message of this.cache.messages.values()) {
      if (predicate(message)) {
        return message
      }
    }
    return undefined
  }

  /**
   * 过滤消息
   */
  filterMessages(predicate: (message: MessageItem) => boolean): MessageItem[] {
    return this.getAllMessages().filter(predicate)
  }

  /**
   * 获取发送失败的消息
   */
  getFailedMessages(): MessageItem[] {
    return this.filterMessages(msg => msg._failed === true)
  }

  /**
   * 获取正在发送的消息
   */
  getSendingMessages(): MessageItem[] {
    return this.filterMessages(msg => msg._sending === true)
  }

  /**
   * 获取本地临时消息
   */
  getLocalMessages(): MessageItem[] {
    return this.filterMessages(msg => msg._local === true)
  }
}

/**
 * 创建消息管理器实例
 */
export function createMessageManager(maxCacheSize?: number): MessageManager {
  return new MessageManager(maxCacheSize)
}

/**
 * 消息去重工具函数
 */
export function deduplicateMessages(messages: MessageItem[]): MessageItem[] {
  const manager = createMessageManager()
  manager.addMessages(messages)
  return manager.getAllMessages()
}

/**
 * 合并消息列表（去重并保持顺序）
 */
export function mergeMessages(existingMessages: MessageItem[], newMessages: MessageItem[]): MessageItem[] {
  const manager = createMessageManager()
  
  // 先添加现有消息
  manager.addMessages(existingMessages)
  
  // 再添加新消息
  const result = manager.addMessages(newMessages)
  
  return {
    allMessages: manager.getAllMessages(),
    newCount: result.newMessages.length,
    updatedCount: result.updatedMessages.length
  } as any
}