import type { StateCreator } from "zustand";
import type { LessonPlanDocument } from "../types";
import type { EditorState } from "./use-lesson-plan-editor";

/** V5-2：撤销/重做栈上限（用户要求至少 50 步） */
export const MAX_HISTORY = 50;

/** 历史快照（仅记录 doc + title，避免完整 state 序列化） */
export interface HistorySnapshot {
  doc: LessonPlanDocument;
  title: string;
}

export interface HistorySlice {
  past: HistorySnapshot[];
  future: HistorySnapshot[];
  canUndo: () => boolean;
  canRedo: () => boolean;
  /** 在 mutation 之前调用：把当前 doc+title 推入 past，清空 future */
  pushHistory: () => void;
  undo: () => void;
  redo: () => void;
  /** hydrate/replaceDoc 时清空历史，避免跨课案污染 */
  clearHistory: () => void;
}

export const createHistorySlice: StateCreator<
  EditorState,
  [],
  [],
  HistorySlice
> = (set, get) => ({
  past: [],
  future: [],

  canUndo: () => get().past.length > 0,
  canRedo: () => get().future.length > 0,

  pushHistory: () => {
    const state = get();
    const snapshot: HistorySnapshot = { doc: state.doc, title: state.title };
    set((s) => ({
      past: [...s.past, snapshot].slice(-MAX_HISTORY),
      future: [], // 新动作清空 redo 栈
    }));
  },

  undo: () => {
    const state = get();
    if (state.past.length === 0) return;
    const previous = state.past[state.past.length - 1]!;
    const current: HistorySnapshot = { doc: state.doc, title: state.title };
    set((s) => ({
      doc: previous.doc,
      title: previous.title,
      past: s.past.slice(0, -1),
      future: [current, ...s.future].slice(0, MAX_HISTORY),
      isDirty: true,
      selectedNodeId: null, // 撤销后重置选中节点，避免悬空引用
    }));
  },

  redo: () => {
    const state = get();
    if (state.future.length === 0) return;
    const next = state.future[0]!;
    const current: HistorySnapshot = { doc: state.doc, title: state.title };
    set((s) => ({
      doc: next.doc,
      title: next.title,
      past: [...s.past, current].slice(-MAX_HISTORY),
      future: s.future.slice(1),
      isDirty: true,
      selectedNodeId: null,
    }));
  },

  clearHistory: () => set({ past: [], future: [] }),
});
