/**
 * History Manager - 历史记录管理器
 * 
 * 职责：
 * - 管理操作历史栈
 * - 支持撤销/重做
 * - 自动限制历史记录数量
 * 
 * 设计原则：
 * - 不可变数据快照
 * - 高效内存管理
 * - 简洁API
 */

import type { SerializedGraph } from './types'

/** 历史记录项 */
interface HistoryItem {
  /** 序列化的图数据快照 */
  data: SerializedGraph
  /** 操作描述（可选） */
  action?: string
  /** 时间戳 */
  timestamp: number
}

/** 历史管理器配置 */
interface HistoryManagerOptions {
  /** 最大历史记录数量，默认 50 */
  maxHistory?: number
}

/**
 * 历史记录管理器
 * 
 * 使用示例：
 * ```ts
 * const history = new HistoryManager()
 * 
 * // 保存状态
 * history.push(graph.serialize(), '添加节点')
 * 
 * // 撤销
 * if (history.canUndo) {
 *   const prev = history.undo()
 *   graph.load(prev.data)
 * }
 * 
 * // 重做
 * if (history.canRedo) {
 *   const next = history.redo()
 *   graph.load(next.data)
 * }
 * ```
 */
export class HistoryManager {
  /** 历史记录栈 */
  private stack: HistoryItem[] = []
  
  /** 当前位置指针（指向当前状态） */
  private pointer: number = -1
  
  /** 最大历史记录数量 */
  private maxHistory: number
  
  constructor(options: HistoryManagerOptions = {}) {
    this.maxHistory = options.maxHistory ?? 50
  }
  
  // ===== 公共属性 =====
  
  /** 是否可以撤销 */
  get canUndo(): boolean {
    return this.pointer > 0
  }
  
  /** 是否可以重做 */
  get canRedo(): boolean {
    return this.pointer < this.stack.length - 1
  }
  
  /** 历史记录数量 */
  get length(): number {
    return this.stack.length
  }
  
  /** 当前位置 */
  get currentIndex(): number {
    return this.pointer
  }
  
  // ===== 公共方法 =====
  
  /**
   * 保存状态到历史记录
   * @param data 图数据快照
   * @param action 操作描述（可选）
   */
  push(data: SerializedGraph, action?: string): void {
    // 创建深拷贝，避免引用问题
    const snapshot: HistoryItem = {
      data: JSON.parse(JSON.stringify(data)),
      action,
      timestamp: Date.now()
    }
    
    // 如果当前位置不是栈顶，删除之后的所有记录
    if (this.pointer < this.stack.length - 1) {
      this.stack = this.stack.slice(0, this.pointer + 1)
    }
    
    // 添加新记录
    this.stack.push(snapshot)
    this.pointer = this.stack.length - 1
    
    // 限制历史记录数量
    if (this.stack.length > this.maxHistory) {
      this.stack.shift()
      this.pointer--
    }
  }
  
  /**
   * 撤销操作
   * @returns 上一个历史状态，如果无法撤销则返回 null
   */
  undo(): HistoryItem | null {
    if (!this.canUndo) return null
    
    this.pointer--
    return this.stack[this.pointer]
  }
  
  /**
   * 重做操作
   * @returns 下一个历史状态，如果无法重做则返回 null
   */
  redo(): HistoryItem | null {
    if (!this.canRedo) return null
    
    this.pointer++
    return this.stack[this.pointer]
  }
  
  /**
   * 获取当前状态
   */
  getCurrent(): HistoryItem | null {
    if (this.pointer < 0 || this.pointer >= this.stack.length) return null
    return this.stack[this.pointer]
  }
  
  /**
   * 获取指定位置的历史记录
   */
  getAt(index: number): HistoryItem | null {
    if (index < 0 || index >= this.stack.length) return null
    return this.stack[index]
  }
  
  /**
   * 清空历史记录
   */
  clear(): void {
    this.stack = []
    this.pointer = -1
  }
  
  /**
   * 初始化历史记录（设置初始状态但不增加指针位置）
   * 用于加载已有数据时初始化历史
   */
  init(data: SerializedGraph): void {
    this.clear()
    const snapshot: HistoryItem = {
      data: JSON.parse(JSON.stringify(data)),
      action: 'Initial',
      timestamp: Date.now()
    }
    this.stack.push(snapshot)
    this.pointer = 0
  }
  
  /**
   * 替换当前状态（不移动指针）
   * 用于微小更新（如拖动时的连续位置变化）
   */
  replaceCurrent(data: SerializedGraph, action?: string): void {
    if (this.pointer < 0) {
      this.push(data, action)
      return
    }
    
    this.stack[this.pointer] = {
      data: JSON.parse(JSON.stringify(data)),
      action,
      timestamp: Date.now()
    }
  }
}

export default HistoryManager
