// Nén ảnh panorama + modal, backup bản gốc, sinh ảnh mờ (LQIP).
// Chạy: node scripts/optimize-images.mjs  (chạy lại nhiều lần an toàn — luôn nén từ backup gốc)
import sharp from "sharp";
import { promises as fs } from "node:fs";
import path from "node:path";

const ROOT = process.cwd();
const PANO_DIR = path.join(ROOT, "public/images/chua-thai-lac");
const MODAL_DIR = path.join(ROOT, "public/modal");
const BACKUP_DIR = path.join(ROOT, "image-originals");
const LQIP_OUT = path.join(ROOT, "src/app/tours/chua-thai-lac.lqip.ts");

const PANO_WIDTH = 4096;
const PANO_WEBP_QUALITY = 72;
const PANO_QUALITY = 80;
const LQIP_WIDTH = 32;
const MODAL_FILES = ["modal-1.png", "modal-2.png"];

const fmt = (b) => (b / 1024 / 1024).toFixed(2) + "MB";
const ensureDir = (d) => fs.mkdir(d, { recursive: true });
const exists = (p) => fs.access(p).then(() => true).catch(() => false);

// Đảm bảo ảnh gốc đã được backup; luôn ĐỌC từ backup để không nén chồng.
async function sourceFrom(destPath, backupSubdir) {
  const name = path.basename(destPath);
  const backupPath = path.join(BACKUP_DIR, backupSubdir, name);
  await ensureDir(path.dirname(backupPath));
  if (!(await exists(backupPath))) {
    await fs.copyFile(destPath, backupPath);
  }
  return backupPath;
}

async function optimizePanoramas() {
  const files = (await fs.readdir(PANO_DIR)).filter((f) => /\.jpe?g$/i.test(f)).sort();
  const lqip = {};
  for (const f of files) {
    const dest = path.join(PANO_DIR, f);
    const src = await sourceFrom(dest, "chua-thai-lac");
    const before = (await fs.stat(dest)).size;

    // JPEG (giữ cho next/image ở trang landing) — cũng hạ về 4096
    const jpgBuf = await sharp(src)
      .rotate()
      .resize({ width: PANO_WIDTH, withoutEnlargement: true })
      .jpeg({ quality: PANO_QUALITY, mozjpeg: true, progressive: true })
      .toBuffer();
    await fs.writeFile(dest, jpgBuf);

    // WebP (tour viewer nạp bản này) — cùng tên, đuôi .webp
    const webpName = f.replace(/\.jpe?g$/i, ".webp");
    const webpDest = path.join(PANO_DIR, webpName);
    const webpBuf = await sharp(src)
      .rotate()
      .resize({ width: PANO_WIDTH, withoutEnlargement: true })
      .webp({ quality: PANO_WEBP_QUALITY, effort: 6 })
      .toBuffer();
    await fs.writeFile(webpDest, webpBuf);

    // LQIP khóa theo path .webp (đúng path tour yêu cầu)
    const lqipBuf = await sharp(src).rotate().resize({ width: LQIP_WIDTH }).jpeg({ quality: 40 }).toBuffer();
    lqip["/images/chua-thai-lac/" + webpName] = "data:image/jpeg;base64," + lqipBuf.toString("base64");

    console.log(
      `${f}: ${fmt(before)} -> jpg ${fmt(jpgBuf.length)} | webp ${fmt(webpBuf.length)}`,
    );
  }
  return lqip;
}

async function optimizeModals() {
  for (const f of MODAL_FILES) {
    const dest = path.join(MODAL_DIR, f);
    if (!(await exists(dest))) continue;
    const src = await sourceFrom(dest, "modal");
    const before = (await fs.stat(dest)).size;
    const buf = await sharp(src).png({ compressionLevel: 9, palette: true, quality: 90, dither: 1 }).toBuffer();
    await fs.writeFile(dest, buf);
    console.log(`${f}: ${fmt(before)} -> ${fmt(buf.length)}`);
  }
}

async function writeLqip(lqip) {
  const entries = Object.entries(lqip)
    .map(([k, v]) => `  ${JSON.stringify(k)}: ${JSON.stringify(v)},`)
    .join("\n");
  const content =
    "// TỰ ĐỘNG SINH bởi scripts/optimize-images.mjs — KHÔNG sửa tay.\n" +
    "// Ảnh mờ tạm (blur-up/LQIP) base64 cho mỗi panorama, khoá theo đường dẫn ảnh.\n" +
    "export const lqip: Record<string, string> = {\n" +
    entries +
    "\n};\n";
  await fs.writeFile(LQIP_OUT, content);
  console.log("Wrote " + path.relative(ROOT, LQIP_OUT) + " (" + Object.keys(lqip).length + " entries)");
}

try {
  const lqip = await optimizePanoramas();
  await optimizeModals();
  await writeLqip(lqip);
  console.log("Done.");
} catch (err) {
  console.error("optimize-images failed:", err);
  process.exit(1);
}
