import { defineNuxtModule, useLogger } from "@nuxt/kit";
import { copyFile, mkdir, readdir, readFile } from "fs/promises";
import { join } from "path";
import { createHash } from "crypto";
import { existsSync, watch } from "fs";

export default defineNuxtModule({
  meta: {
    name: "content-assets",
    configKey: "contentAssets",
  },
  defaults: {},
  async setup(_, nuxt) {
    const logger = useLogger("content-assets");
    const contentDir = join(nuxt.options.rootDir, "content");
    const publicDir = join(
      nuxt.options.rootDir,
      "public/nds/images/projects/pokemons",
    );

    const getFileChecksum = async (filePath: string): Promise<string> => {
      const content = await readFile(filePath);
      return createHash("sha256").update(content).digest("hex");
    };

    const copyWebpFiles = async () => {
      try {
        const projectsDir = join(contentDir, "projects");

        if (!existsSync(projectsDir)) {
          logger.info("No projects directory found");
          return;
        }

        if (!existsSync(publicDir)) {
          await mkdir(publicDir, { recursive: true });
        }

        const entries = await readdir(projectsDir, { withFileTypes: true });

        for (const entry of entries) {
          if (!entry.isDirectory()) continue;

          const projectName = entry.name;
          const sourcePath = join(projectsDir, projectName, "index.webp");
          const destPath = join(publicDir, `${projectName}.webp`);

          if (!existsSync(sourcePath)) {
            continue;
          }

          // only copy if destination doesn't exist, or if not the same as source
          let shouldCopy = true;
          if (existsSync(destPath)) {
            const sourceChecksum = await getFileChecksum(sourcePath);
            const destChecksum = await getFileChecksum(destPath);

            if (sourceChecksum === destChecksum) {
              shouldCopy = false;
            }
          }

          if (shouldCopy) {
            await copyFile(sourcePath, destPath);
            logger.success(
              `Copied: ${projectName}/index.webp -> ${projectName}.webp`,
            );
          }
        }
      } catch (error) {
        logger.error("Error copying files:", error);
      }
    };

    nuxt.hook("build:before", async () => {
      await copyWebpFiles();
    });

    if (nuxt.options.dev) {
      nuxt.hook("ready", () => {
        watch(contentDir, { recursive: true }, async (_, filePath) => {
          // NOTE: only match /PROJECT_NAME/index.webp
          if (filePath?.endsWith("/index.webp")) {
            logger.info(`Detected change: ${filePath}`);
            await copyWebpFiles();
          }
        });
      });
    }
  },
});
