import "reflect-metadata";
import { config } from "dotenv";
import { statSync } from "fs";
import { readdir } from "fs/promises";
import { extname, join, relative } from "path";
import { AppDataSource } from "../data-source";
import { MediaAsset } from "../media/entities/media-asset.entity";

config();

// Backfills the media library with every image already sitting in the
// frontend's public/ folder (hero images, team photos, process steps,
// etc.) — these were never "uploaded" through the admin, they've just
// always been part of the site, but the library should still be able to
// find and reuse them. Safe to re-run: skips any url already recorded.
const MIME_BY_EXT: Record<string, string> = {
  ".jpg": "image/jpeg",
  ".jpeg": "image/jpeg",
  ".png": "image/png",
  ".webp": "image/webp",
  ".gif": "image/gif",
  ".svg": "image/svg+xml",
};

async function walk(dir: string): Promise<string[]> {
  const entries = await readdir(dir, { withFileTypes: true });
  const files: string[] = [];
  for (const entry of entries) {
    const full = join(dir, entry.name);
    if (entry.isDirectory()) {
      files.push(...(await walk(full)));
    } else if (MIME_BY_EXT[extname(entry.name).toLowerCase()]) {
      files.push(full);
    }
  }
  return files;
}

async function main() {
  const frontendDir = process.env.FRONTEND_DIR;
  if (!frontendDir) {
    console.error("FRONTEND_DIR is not set in .env — can't locate the frontend's public/ folder.");
    process.exit(1);
  }
  const publicDir = join(frontendDir, "public");

  const dataSource = await AppDataSource.initialize();
  const repo = dataSource.getRepository(MediaAsset);

  const files = await walk(publicDir);
  const existingUrls = new Set((await repo.find()).map((a) => a.url));

  let created = 0;
  for (const filePath of files) {
    const relPath = relative(publicDir, filePath).split("\\").join("/");
    const url = `/${relPath}`;
    if (existingUrls.has(url)) continue;

    const ext = extname(filePath).toLowerCase();
    const stat = statSync(filePath);
    await repo.save(
      repo.create({
        fileName: relPath,
        originalName: relPath.split("/").pop()!,
        url,
        mimeType: MIME_BY_EXT[ext],
        sizeBytes: stat.size,
      }),
    );
    created++;
  }

  console.log(`Scanned ${files.length} image files under ${publicDir}.`);
  console.log(`Added ${created} new media library entries (${files.length - created} already tracked).`);

  await dataSource.destroy();
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});
