#!/usr/bin/env node
import { promises as fs } from "fs";
import path from "path";
import { fileURLToPath } from "url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRoot = path.resolve(__dirname, "..");
const funnelsDir = path.join(projectRoot, "public", "funnels");
const outputFile = path.join(projectRoot, "src", "lib", "funnel", "bakedFunnels.ts");

/**
 * Нормализует данные воронки перед запеканием
 * Удаляет поля которые не соответствуют типам TypeScript
 */
function normalizeFunnelData(funnelData) {
  return {
    ...funnelData,
    screens: funnelData.screens.map((screen) => {
      const normalizedScreen = { ...screen };
      
      // Удаляем variables из экранов, которые не поддерживают это поле
      // variables поддерживается только в info экранах
      if ('variables' in normalizedScreen && normalizedScreen.template !== 'info') {
        delete normalizedScreen.variables;
      }
      
      return normalizedScreen;
    }),
  };
}

function formatFunnelRecord(funnels) {
  const entries = Object.entries(funnels)
    .map(([funnelId, definition]) => {
      const serialized = JSON.stringify(definition, null, 2);
      const indented = serialized
        .split("\n")
        .map((line, index) => (index === 0 ? line : `  ${line}`))
        .join("\n");
      return `  "${funnelId}": ${indented}`;
    })
    .join(",\n\n");

  return `{
${entries}\n}`;
}

async function bakeFunnels() {
  const dirExists = await fs
    .access(funnelsDir)
    .then(() => true)
    .catch(() => false);

  if (!dirExists) {
    throw new Error(`Funnels directory not found: ${funnelsDir}`);
  }

  const files = (await fs.readdir(funnelsDir)).sort((a, b) => a.localeCompare(b));
  const funnels = {};

  for (const file of files) {
    if (!file.endsWith(".json")) continue;

    const filePath = path.join(funnelsDir, file);
    const raw = await fs.readFile(filePath, "utf8");

    let parsed;
    try {
      parsed = JSON.parse(raw);
    } catch (error) {
      throw new Error(`Failed to parse ${file}: ${error.message}`);
    }

    const funnelId = parsed?.meta?.id ?? parsed?.id ?? file.replace(/\.json$/, "");

    if (!funnelId || typeof funnelId !== "string") {
      throw new Error(
        `Unable to determine funnel id for '${file}'. Ensure the file contains an 'id' or 'meta.id' field.`
      );
    }

    // Нормализуем данные перед запеканием
    funnels[funnelId] = normalizeFunnelData(parsed);
  }

  const headerComment = `/**\n * This file is auto-generated by scripts/bake-funnels.mjs.\n * Do not edit this file manually; update the source JSON files instead.\n */`;

  const recordLiteral = formatFunnelRecord(funnels);
  const contents = `${headerComment}\n\nimport type { FunnelDefinition } from "./types";\n\nexport const BAKED_FUNNELS: Record<string, FunnelDefinition> = ${recordLiteral};\n`;

  await fs.mkdir(path.dirname(outputFile), { recursive: true });
  await fs.writeFile(outputFile, contents, "utf8");

  console.log(`Baked ${Object.keys(funnels).length} funnel(s) into ${path.relative(projectRoot, outputFile)}`);
}

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