import fs from "node:fs";
import path from "node:path";
import { type CommandResult, success } from "../../../lib/command-result";
// Static imports of internal module seed data (bundled into CLI)
import * as primitivesSeed from "../../../../modules/primitives/seed";

type SeedMap = Record<string, Record<string, unknown>>;

// Module name → seed exports. Add new modules here as they gain seed data.
const INTERNAL_SEED: Record<string, Record<string, unknown>> = {
  primitives: primitivesSeed,
};

function mapToJsonl(data: SeedMap): string {
  return (
    Object.entries(data)
      .map(([id, row]) => JSON.stringify({ id, ...row }))
      .join("\n") + "\n"
  );
}

function capitalize(s: string): string {
  return s.charAt(0).toUpperCase() + s.slice(1);
}

/**
 * Checks if a value is a seed data map: Record<string, Record<string, unknown>>.
 * Distinguishes from ID maps (Record<string, string>) by checking nested values.
 */
function isSeedMap(value: [string, unknown]): value is [string, SeedMap] {
  if (typeof value[1] !== "object" || value[1] === null || Array.isArray(value[1])) return false;
  const entries = Object.entries(value[1] as Record<string, unknown>);
  if (entries.length === 0) return false;
  return entries.every(([, v]) => typeof v === "object" && v !== null && !Array.isArray(v));
}

export function runAppGenerateSeed(appPath: string): CommandResult {
  const seedDir = path.join(appPath, "backend", "seed", "data");
  fs.mkdirSync(seedDir, { recursive: true });

  let written = 0;
  let skipped = 0;
  const modulesWithSeed: string[] = [];

  for (const [moduleName, mod] of Object.entries(INTERNAL_SEED)) {
    const entries = Object.entries(mod).filter((mod) => isSeedMap(mod));
    if (entries.length === 0) continue;

    modulesWithSeed.push(moduleName);

    for (const [exportName, data] of entries) {
      const fileName = capitalize(exportName);
      const filePath = path.join(seedDir, `${fileName}.jsonl`);
      if (fs.existsSync(filePath)) {
        console.log(`  skipped ${fileName}.jsonl (already exists)`);
        skipped++;
        continue;
      }
      const rowCount = Object.keys(data).length;
      fs.writeFileSync(filePath, mapToJsonl(data));
      console.log(`  wrote ${fileName}.jsonl (${rowCount} rows)`);
      written++;
    }
  }

  console.log(`\nModules with seed data: ${modulesWithSeed.join(", ") || "none"}`);
  console.log(`Generated ${written} file(s), skipped ${skipped} existing`);
  return success();
}
