const { ipcMain } = require('electron');
const path = require('path');
const fs = require('fs');
const crypto = require('crypto');

const EXTS = new Set(['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.tif', '.webp', '.heic', '.heif']);

function register() {
  ipcMain.handle('list-images', async (_event, folderPath) => {
    try {
      const files = fs.readdirSync(folderPath)
        .filter(f => EXTS.has(path.extname(f).toLowerCase()))
        .map(f => {
          const fullPath = path.join(folderPath, f);
          const stat = fs.statSync(fullPath);
          return { name: f, path: fullPath, mtime: stat.mtimeMs };
        })
        .sort((a, b) => a.name.localeCompare(b.name, 'ko'));
      return files;
    } catch (e) {
      return [];
    }
  });

  ipcMain.handle('read-image', async (_event, filePath) => {
    try {
      const data = fs.readFileSync(filePath);
      const ext = path.extname(filePath).toLowerCase().replace('.', '');
      const mime = (ext === 'jpg' || ext === 'jpeg')   ? 'jpeg'
                 : ext === 'png'                       ? 'png'
                 : ext === 'gif'                       ? 'gif'
                 : ext === 'webp'                      ? 'webp'
                 : (ext === 'tiff' || ext === 'tif')   ? 'tiff'
                 : ext === 'bmp'                       ? 'bmp'
                 : (ext === 'heic' || ext === 'heif')  ? 'heic'
                 : 'jpeg';
      return `data:image/${mime};base64,${data.toString('base64')}`;
    } catch (e) {
      return null;
    }
  });

  ipcMain.handle('check-files-exist', (_event, folderPath, names) => {
    return names.filter(name => {
      try { fs.accessSync(path.join(folderPath, name)); return true; }
      catch { return false; }
    });
  });

  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 {
        fs.renameSync(file.path, dest);
        moved.push({ src: file.path, dest, name: destName });
      } catch (e) {
        if (e.code === 'EXDEV') {
          try {
            fs.copyFileSync(file.path, dest);
            fs.unlinkSync(file.path);
            moved.push({ src: file.path, dest, name: destName });
          } catch (e2) {
            errors.push(`${file.name}: ${e2.message}`);
          }
        } else {
          errors.push(`${file.name}: ${e.message}`);
        }
      }
    }
    return { moved, 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 };