import { state } from './state.js';
import { setStatus, showToast } from './ui.js';
import { renderGrid, showEmptyGrid } from './grid.js';
import * as history from './history.js';

export function createHistoryController({
  btnRename,
  btnUndo,
  btnRedo,
  updateSortButtons,
}) {
  let busy = false;

  function updateButtons() {
    btnUndo.disabled = !history.canUndo();
    btnRedo.disabled = !history.canRedo();
  }

  async function performUndo() {
    if (busy || !history.canUndo()) {
      if (!history.canUndo()) showToast('더 이상 되돌릴 수 없습니다');
      return;
    }

    busy = true;
    try {
      const { entry, targetFiles } = history.undo();
      if (entry.type === 'delete') {
        const { restored, errors } = await window.api.restoreStagedFiles(entry.deletedEntries);
        if (errors.length) showToast('일부 파일 복원 실패: ' + errors[0]);
        applySnapshot(targetFiles, new Set(restored));
        if (restored.length) setStatus(`${restored.length}개 파일 복원됨`, true);
      } else {
        applySnapshot(targetFiles, entry.affectedPaths);
      }
    } finally {
      busy = false;
    }
  }

  async function performRedo() {
    if (busy || !history.canRedo()) {
      if (!history.canRedo()) showToast('마지막 작업 상태입니다');
      return;
    }

    busy = true;
    try {
      const nextEntry = history.peekRedo();
      if (nextEntry.type === 'delete') {
        const pathsToRedo = nextEntry.deletedEntries.map(e => e.originalPath);
        const { staged, errors } = await window.api.stageDeleteFiles(pathsToRedo);
        if (errors.length) showToast('일부 파일 삭제 실패: ' + errors[0]);
        updateDeleteStagingPaths(nextEntry, staged);
        const { targetFiles } = history.redo();
        applySnapshot(targetFiles, null);
        if (staged.length) setStatus(`${staged.length}개 파일 삭제됨`, true);
      } else {
        const { entry, targetFiles } = history.redo();
        applySnapshot(targetFiles, entry.affectedPaths);
      }
    } finally {
      busy = false;
    }
  }

  function applySnapshot(targetFiles, affectedPaths = null) {
    state.files.length = 0;
    state.files.push(...targetFiles);
    state.selectedIdxs.clear();

    if (affectedPaths && affectedPaths.size > 0) {
      const pathToIdx = new Map(state.files.map((f, i) => [f.path, i]));
      affectedPaths.forEach(p => {
        const idx = pathToIdx.get(p);
        if (idx !== undefined) state.selectedIdxs.add(idx);
      });
    }

    state.sortMode = null;
    updateSortButtons();
    if (!state.files.length) {
      showEmptyGrid();
      btnRename.disabled = true;
    } else {
      renderGrid();
      btnRename.disabled = false;
    }
    updateButtons();
  }

  return { performUndo, performRedo, updateButtons };
}

function updateDeleteStagingPaths(entry, staged) {
  const stagedByPath = new Map(staged.map(s => [s.originalPath, s.stagingPath]));
  entry.deletedEntries.forEach(e => {
    if (stagedByPath.has(e.originalPath)) e.stagingPath = stagedByPath.get(e.originalPath);
  });
}
