/**
 * Creates or updates an academic program from the command line.
 *
 * Programs are normally managed in the Programs screen; this exists so an
 * installation can be provisioned before anyone has signed in.
 *
 *   npm run program -- --code NUR --name "College of Nursing"
 */
import { getDb, newId, nowIso } from "@/lib/db";
import { recordAudit } from "@/lib/audit";

function arg(name: string): string | undefined {
  const index = process.argv.indexOf(`--${name}`);
  return index === -1 ? undefined : process.argv[index + 1];
}

const code = arg("code")?.trim().toUpperCase();
const name = arg("name")?.trim();
const notes = arg("notes")?.trim() ?? null;

if (!code || !name) {
  console.error('Usage: npm run program -- --code NUR --name "College of Nursing" [--notes "..."]');
  process.exit(1);
}
if (!/^[A-Za-z0-9-]+$/.test(code)) {
  console.error("Program code must contain only letters, numbers and hyphens.");
  process.exit(1);
}

const db = await getDb();
const existing = await db.get<{ id: string; name: string }>("SELECT id, name FROM programs WHERE code = ?", [code]);
const ts = nowIso();

if (existing) {
  await db.run("UPDATE programs SET name = ?, active = 1, updated_at = ? WHERE id = ?", [name, ts, existing.id]);
  await recordAudit({
    actor: null,
    action: "PROGRAM_UPDATED",
    entityType: "program",
    entityId: existing.id,
    before: { code, name: existing.name },
    after: { code, name },
    reason: "Updated from the command line during setup.",
  });
  console.log(`Updated program ${code} — ${name}`);
} else {
  const id = newId();
  await db.run(
    "INSERT INTO programs (id, code, name, active, notes, created_at, updated_at) VALUES (?, ?, ?, 1, ?, ?, ?)",
    [id, code, name, notes, ts, ts],
  );
  await recordAudit({
    actor: null,
    action: "PROGRAM_CREATED",
    entityType: "program",
    entityId: id,
    after: { code, name },
    reason: "Created from the command line during setup.",
  });
  console.log(`Created program ${code} — ${name}`);
}

const all = await db.all<{ code: string; name: string; n: number }>(
  `SELECT p.code, p.name, COALESCE(s.n, 0) AS n
     FROM programs p
     LEFT JOIN (SELECT program_id, COUNT(*) AS n FROM students WHERE active = 1 GROUP BY program_id) s
            ON s.program_id = p.id
    WHERE p.active = 1
    ORDER BY p.name`,
);
console.log("\nActive programs:");
for (const row of all) console.log(`  ${row.code.padEnd(6)} ${row.name.padEnd(28)} ${row.n} student(s)`);

await db.close();
