import {reactive,  computed} from "vue"
import { ValueSnap } from "./rxValue";

export class HistoryController {
  enable = false;
  state = reactive({
        currLen: 0, //操作栈的长度
        maxLen: 100, //操作栈总长度
        opIndex: -1, //操作栈的指针
  });

  refCanUndo = computed(() => {
    return this.state.opIndex >= 0;
  });
  refCanRedo = computed(() => {
    return this.state.opIndex < this.state.currLen - 1;
  });

  queues: Map<string, ValueSnap>[] = [];
  cacheSnapValues = new Map<string , ValueSnap>();

  changeCbs:((flag:number)=>void)[]  = [];

  // 添加缓存记录
  record(snap: ValueSnap) {
    if ( !this.enable ) return;

    const first = this.cacheSnapValues.get(snap.Id)
    if (first) {
        snap.OldValue = first.OldValue;
    }
    this.cacheSnapValues.set(snap.Id, snap);
  }

  // 保存缓存记录到历史栈中
  submit(change:(flag:number)=>void=(flag)=>{console.log("default history changed ", flag)}) {
    if (this.cacheSnapValues.size < 1  || !this.enable) return;

    console.log("submiting history=>", this.cacheSnapValues.size);
    const state = this.state;
    const queue = this.queues;

    // 将缓存操作记录保存到当前指针的下一栈中
    const index = ++state.opIndex;
    queue[index] = this.cacheSnapValues;
    this.changeCbs[index] = change;

    // 重置缓存记录
    this.cacheSnapValues = new Map<string, ValueSnap>();

    // 设置栈的长度为指针的长度，舍弃后面的记录
    queue.length = state.opIndex + 1;
    // 若栈长度超过上限, 舍弃之前的记录
    if (queue.length > state.maxLen) {
      queue.splice(0, queue.length - state.maxLen);
      state.opIndex = state.maxLen - 1;
    }
    // 更新当前长度状态
    state.currLen = queue.length;
  }

  undo() {
    if (!this.refCanUndo.value || !this.enable ) return;

    this.cacheSnapValues = new Map<string, ValueSnap>();
    const index = this.state.opIndex--;
    const snaps = this.queues[index]

    snaps.forEach((vn)=>vn.undo())

    const cb = this.changeCbs[index];
  
    cb && cb(1);
  }

  redo() {
    if (!this.refCanRedo.value  || !this.enable) return;

    this.cacheSnapValues = new Map<string, ValueSnap>();
    const index = ++this.state.opIndex;
    const snaps = this.queues[index];
    snaps.forEach(vn=>vn.redo());

    const cb = this.changeCbs[index];
    cb && cb(2);
  }

  //清除操作
  clear() {
    if ( !this.enable ) return;

    this.queues = [];
    this.changeCbs = [];
    this.state.currLen = 0;
    this.state.opIndex = -1;
    this.cacheSnapValues = new Map<string, ValueSnap>();
  }
}