/**
 * create-plan-development CLI — Entry point.
 *
 * Reads the .smartstack/ba/ tree for selected applications, parses entité.md
 * files to extract cross-module FK dependencies, builds a dependency graph,
 * topological-sorts into parallel development waves, and writes dev-plan.md.
 *
 * Usage:
 *   npx tsx skills/business-analyse/create-plan-development/cli/create-plan-development/index.ts \
 *     --spec '{"baRoot": ".smartstack/ba", "apps": ["CRM", "BILLING"]}'
 */
import { parseArgs } from 'node:util';
import path from 'node:path';
import { generateEnvelope, failGenerate, printEnvelope } from '../../../../lib/output.js';
import { ensureDirectory, writeText, writeJson } from '../../../../lib/fs.js';
import { validate } from './validate.js';
import { parseModules } from './parse.js';
import { buildPlan } from './graph.js';
import { generatePlan } from './generate.js';

const COMMAND = 'create-plan-development';

async function main(): Promise<void> {
  // --- 1. Parse CLI arguments ---
  const { values } = parseArgs({
    options: {
      spec: { type: 'string' },
    },
    strict: false,
  });

  if (!values.spec) {
    printEnvelope(failGenerate(COMMAND, ['Missing required --spec argument']));
    process.exit(1);
  }

  let raw: unknown;
  try {
    raw = JSON.parse(values.spec);
  } catch {
    printEnvelope(failGenerate(COMMAND, ['Invalid JSON in --spec argument']));
    process.exit(1);
  }

  // --- 2. Validate ---
  const validation = await validate(raw);
  if (!validation.valid || !validation.spec || !validation.discoveredModules) {
    printEnvelope(failGenerate(COMMAND, validation.errors));
    process.exit(1);
  }

  const spec = validation.spec;
  const allWarnings = [...validation.warnings];

  // --- 3. Parse entité.md files ---
  const { modules, warnings: parseWarnings } = await parseModules(
    spec,
    validation.discoveredModules,
  );
  allWarnings.push(...parseWarnings);

  // --- 4. Build dependency graph + topological sort ---
  const plan = buildPlan(modules, spec.apps);
  allWarnings.push(...plan.warnings);

  // --- 5. Generate markdown ---
  const outputPath = path.join(spec.baRoot, '_plan', 'dev-plan.md');
  const file = generatePlan(plan, outputPath);

  // --- 6. Write files (markdown + JSON sidecar for ba-develop-plan) ---
  await ensureDirectory(path.dirname(file.path));
  await writeText(file.path, file.content);

  const jsonPath = path.join(spec.baRoot, '_plan', 'dev-plan.json');
  await writeJson(jsonPath, plan);

  // --- 7. Print envelope ---
  const devWaves = plan.waves.filter((w) => w.level > 0);
  const externalCount = plan.waves.find((w) => w.level === 0)?.modules.length ?? 0;

  printEnvelope(
    generateEnvelope(COMMAND, {
      data: {
        appCount: spec.apps.length,
        moduleCount: plan.totalModules,
        waveCount: devWaves.length,
        cycleCount: plan.cycles.length,
        externalDepCount: externalCount,
      },
      filesCreated: [path.resolve(file.path), path.resolve(jsonPath)],
      warnings: allWarnings,
      nextSteps: [
        `Review the plan: ${outputPath}`,
        'Run /ba-develop for Wave 1 modules first (no cross-module dependencies)',
        'Proceed wave by wave — each wave depends on the previous one',
      ],
    }),
  );
}

main().catch((err) => {
  printEnvelope(
    failGenerate(COMMAND, [err instanceof Error ? err.message : String(err)]),
  );
  process.exit(1);
});
