import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { basename, dirname, join } from "node:path";
import { fileURLToPath } from "node:url";

const root = dirname(fileURLToPath(import.meta.url));
const frontendRoot = join(root, "..");
const exactRoot = join(frontendRoot, "public", "exact");
const outFile = join(frontendRoot, "src", "routes", "exact-html.ts");
const componentRoot = join(frontendRoot, "src", "routes", "exact-pages");

const pages = [
  ["account", "account.html"],
  ["assetFactory", "asset-factory.html"],
  ["dashboard", "index.html"],
  ["imageOptimize", "image-optimize.html"],
  ["library", "library.html"],
  ["login", "login.html"],
  ["messages", "messages.html"],
  ["modelPhoto", "model-photo.html"],
  ["modelPhotoDemoA", "model-photo-demo-a.html"],
  ["modelPhotoDemoB", "model-photo-demo-b.html"],
  ["pipeline", "pipeline.html"],
  ["platformCover", "platform-cover.html"],
  ["productCreate", "product-create.html"],
  ["productCreateUpload", "product-create-upload.html"],
  ["productDetail", "product-detail.html"],
  ["products", "products.html"],
  ["projectWizard", "projects-new.html"],
  ["projects", "projects.html"],
  ["register", "register.html"],
  ["settings", "settings.html"],
  ["team", "team.html"]
];

function normalizeDocument(html, fileName) {
  const withMeta = html.replace(
    /<head>/i,
    `<head>\n<meta name="x-airshelf-exact-source" content="${basename(fileName)}">`
  );
  return withMeta
    .replace(/(src|href)="assets\//g, '$1="/exact/assets/')
    .replace(/url\((['"]?)assets\//g, "url($1/exact/assets/")
    .replace(
    "history.replaceState(null, '', '#' + id);",
    "try { window.location.hash = id; } catch (e) {}"
    );
}

mkdirSync(dirname(outFile), { recursive: true });
mkdirSync(componentRoot, { recursive: true });

const entries = pages
  .map(([key, fileName]) => {
    const html = normalizeDocument(readFileSync(join(exactRoot, fileName), "utf8"), fileName);
    return `  ${JSON.stringify(key)}: ${JSON.stringify(html)}`;
  })
  .join(",\n");

const keys = pages.map(([key]) => JSON.stringify(key)).join(" | ");

writeFileSync(
  outFile,
  `/* This file is generated by scripts/generate-exact-html.mjs. Do not edit by hand. */\n` +
    `export type ExactHtmlKey = ${keys};\n\n` +
    `export const exactHtmlDocuments: Record<ExactHtmlKey, string> = {\n${entries}\n};\n`,
  "utf8"
);

function toPascalCase(value) {
  return value
    .replace(/([a-z0-9])([A-Z])/g, "$1-$2")
    .split(/[-_]/)
    .filter(Boolean)
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
    .join("");
}

for (const [key] of pages) {
  const componentName = `Exact${toPascalCase(key)}Page`;
  const fileName = `${key.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase()}.tsx`;
  writeFileSync(
    join(componentRoot, fileName),
    `/* Generated by scripts/generate-exact-html.mjs. Do not edit by hand. */\n` +
      `import { ExactDocumentPage } from "../exact-document";\n` +
      `import type { ExactDocumentPageProps } from "../exact-document";\n\n` +
      `export function ${componentName}(props: Omit<ExactDocumentPageProps, "pageKey">) {\n` +
      `  return <ExactDocumentPage {...props} pageKey=${JSON.stringify(key)} />;\n` +
      `}\n\n` +
      `export default ${componentName};\n`,
    "utf8"
  );
}

console.log(`generated ${pages.length} exact documents -> ${outFile}`);
