const { ipcMain, app } = require('electron');
const path = require('path');
const fs = require('fs');
const crypto = require('crypto');
const {
  fileExists,
  listImages,
  moveFileWithCopyFallback,
  readImageAsDataUrl,
} = require('./file-utils');

function register() {
  ipcMain.handle('list-images', async (_event, folderPath) => {
    try {
      return listImages(folderPath);
    } catch (e) {
      return [];
    }
  });

  ipcMain.handle('read-image', async (_event, filePath) => {
    try {
      return readImageAsDataUrl(filePath);
    } catch (e) {
      return null;
    }
  });

  ipcMain.handle('check-files-exist', (_event, folderPath, names) => {
    return names.filter(name => fileExists(path.join(folderPath, name)));
  });

  ipcMain.handle('move-files', async (_event, { targetFolder, files }) => {
    const errors = [];
    const moved  = [];
    for (const file of files) {
      const destName = file.newName || file.name;
      const dest = path.join(targetFolder, destName);
      try {
        moveFileWithCopyFallback(file.path, dest);
        moved.push({ src: file.path, dest, name: destName });
      } catch (e) {
        errors.push(`${file.name}: ${e.message}`);
      }
    }
    return { moved, errors };
  });

  // 삭제 → 스테이징 폴더로 이동 (undo 가능)
  ipcMain.handle('stage-delete-files', async (_event, filePaths) => {
    const batchDir = path.join(app.getPath('userData'), 'deleted_staging', Date.now().toString());
    fs.mkdirSync(batchDir, { recursive: true });

    const staged = [];
    const errors = [];
    for (const fp of filePaths) {
      const name = path.basename(fp);
      const dest = path.join(batchDir, name);
      try {
        moveFileWithCopyFallback(fp, dest);
        staged.push({ name, originalPath: fp, stagingPath: dest });
      } catch (e) {
        errors.push(`${name}: ${e.message}`);
      }
    }
    if (!staged.length) try { fs.rmdirSync(batchDir); } catch {}
    return { staged, errors };
  });

  // 스테이징 파일 원래 위치로 복원 (undo delete)
  ipcMain.handle('restore-staged-files', async (_event, deletedEntries) => {
    const restored = [];
    const errors   = [];
    for (const { name, originalPath, stagingPath } of deletedEntries) {
      if (fs.existsSync(originalPath)) {
        errors.push(`${name}: 같은 이름의 파일이 이미 존재합니다`);
        continue;
      }
      try {
        fs.mkdirSync(path.dirname(originalPath), { recursive: true });
        moveFileWithCopyFallback(stagingPath, originalPath);
        restored.push(originalPath);
      } catch (e) {
        errors.push(`${name}: ${e.message}`);
      }
    }
    return { restored, errors };
  });

  ipcMain.handle('rename-files', async (_event, { folderPath, files, prefix, digits }) => {
    const errors = [];
    const pad = (n) => String(n + 1).padStart(digits, '0');

    // 1단계: 임시 이름으로 이동 (충돌 방지)
    const tmpMap = [];
    for (let i = 0; i < files.length; i++) {
      const src = files[i].path;
      const ext = path.extname(files[i].name).toLowerCase();
      const tmp = path.join(folderPath, `__tmp_${crypto.randomUUID()}${ext}`);
      try {
        fs.renameSync(src, tmp);
        tmpMap.push({ tmp, ext, idx: i });
      } catch (e) {
        errors.push(`${files[i].name}: ${e.message}`);
      }
    }

    // 2단계: 최종 이름으로 이동
    const renamed = [];
    for (const { tmp, ext, idx } of tmpMap) {
      const newName = `${prefix}_${pad(idx)}${ext}`;
      const dest = path.join(folderPath, newName);
      try {
        fs.renameSync(tmp, dest);
        renamed.push({ oldPath: tmp, newPath: dest, newName });
      } catch (e) {
        errors.push(`${newName}: ${e.message}`);
      }
    }

    return { renamed, errors };
  });
}

module.exports = { register };
