#!/usr/bin/env node
// Generate cached thumbnails (40px and 200px) for every uploaded product image.
// Pre-generates thumbnails in each app's public/uploads/thumbs/<size>/ directory
// so Next.js serves them as static files.

import { readdir, stat, mkdir, writeFile, readFile } from 'node:fs/promises';
import { dirname, extname, join } from 'node:path';
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const sharp = require(process.env.SHARP_PATH || '/Users/chattie/git/mercadodevida/project/apps/admin/node_modules/sharp');

const PROJECT_DIR = join(import.meta.dirname, '..');
const SIZES = [40, 200];
/**
 * Maximum height ratio (h/w) for cached thumbnails. Mirrors the resize
 * contract used by the upload route and the dynamic `/uploads/[...path]`
 * handler so that batch regeneration and on-demand generation produce the
 * same shape. The thumbnail fits inside a `width × width * MAX_HEIGHT_RATIO`
 * bounding box without cropping, preserving the source aspect ratio.
 */
const MAX_HEIGHT_RATIO = 1.4;
/** Set FORCE=1 to regenerate thumbnails even when the cached file exists. */
const FORCE = process.env.FORCE === '1' || process.env.FORCE === 'true';
const APP_DIRS = [
  join(PROJECT_DIR, 'apps', 'admin'),
  join(PROJECT_DIR, 'frontend'),
  join(PROJECT_DIR, 'storefront'),
];
const SRC_DIR = join(PROJECT_DIR, 'apps', 'admin', 'public', 'uploads');

const VALID_EXTS = new Set(['.jpg', '.jpeg', '.png', '.webp', '.avif', '.gif']);

async function main() {
  let files;
  try {
    files = await readdir(SRC_DIR);
  } catch (err) {
    if (err.code === 'ENOENT') {
      console.log('[INFO] No uploads dir yet, nothing to do');
      return;
    }
    throw err;
  }

  const images = files.filter((f) => VALID_EXTS.has(extname(f).toLowerCase()));
  console.log(`[INFO] Found ${images.length} source images`);

  let generated = 0;
  for (const filename of images) {
    const src = join(SRC_DIR, filename);
    const srcStat = await stat(src);
    if (!srcStat.isFile()) continue;

    for (const appDir of APP_DIRS) {
      // Ensure peer upload exists so the thumbnail is reachable
      const peerPath = join(appDir, 'public', 'uploads', filename);
      try {
        await stat(peerPath);
      } catch {
        // Copy from source if missing (mirror admin's uploads)
        await mkdir(dirname(peerPath), { recursive: true });
        await writeFile(peerPath, await import('node:fs/promises').then((fs) => fs.readFile(src)));
      }

      for (const size of SIZES) {
        // Store as <app>/public/uploads/<size>/<filename> so Next.js serves
        // them as plain static files via URLs like /uploads/40/foo.jpg
        const thumbDir = join(appDir, 'public', 'uploads', String(size));
        const thumbPath = join(thumbDir, filename);

        // Skip if already cached (unless FORCE=1 to regenerate)
        if (!FORCE) {
          try {
            const s = await stat(thumbPath);
            if (s.isFile() && s.size > 0) continue;
          } catch {}
        }

        await mkdir(thumbDir, { recursive: true });
        const maxHeight = Math.round(size * MAX_HEIGHT_RATIO);
        await sharp(src)
          .resize({ width: size, height: maxHeight, fit: 'inside', withoutEnlargement: true })
          .jpeg({ quality: 80 })
          .toFile(thumbPath);
        generated += 1;
      }
    }
  }
  console.log(`[OK] Processed ${images.length} images, generated ${generated} new thumbnails`);
}

main().catch((err) => {
  console.error('[FAIL]', err.message);
  process.exit(1);
});