// DB-Smoke-Test als Standalone-Skript. Wird mit `npm run test:db` aufgerufen.
// Grund: better-sqlite3 segfaultet beim Schließen unter Node 22 + node:test.
// Daher hier als normales assert-Skript ohne den node-Test-Runner.
//
// Aufruf: node --experimental-strip-types src/lib/db/smoke.ts

import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import assert from "node:assert/strict";

const dir = mkdtempSync(join(tmpdir(), "eldov-smoke-"));
process.env.DB_PATH = join(dir, "smoke.db");
process.env.SESSION_SECRET = "0".repeat(64);
process.env.ADMIN_PASSWORD = "test-password-123";

let failures = 0;
function check(label: string, fn: () => void) {
  try {
    fn();
    console.log(`  ✓ ${label}`);
  } catch (e) {
    failures += 1;
    console.error(`  ✗ ${label}`);
    console.error(`    ${(e as Error).message}`);
  }
}

const { getDb, __resetDbForTest } = await import("../db.ts");
const { seedIfEmpty } = await import("../seed.ts");
const { listProjects, getProject, insertProject, updateProject, deleteProject } = await import("../models.ts");

console.log("\n[1] Schema + Seed");
{
  const db = getDb();
  const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name").all() as { name: string }[];
  const names = tables.map((t) => t.name);
  check("profile-Tabelle angelegt", () => assert.ok(names.includes("profile")));
  check("projects-Tabelle angelegt", () => assert.ok(names.includes("projects")));
  check("sessions-Tabelle angelegt", () => assert.ok(names.includes("sessions")));

  const first = seedIfEmpty(db);
  check("Seed #1: profile", () => assert.equal(first.profileSeeded, true));
  check("Seed #1: projects > 0", () => assert.ok(first.projectsSeeded > 0, `got ${first.projectsSeeded}`));

  const second = seedIfEmpty(db);
  check("Seed #2: idempotent (profile)", () => assert.equal(second.profileSeeded, false));
  check("Seed #2: idempotent (projects)", () => assert.equal(second.projectsSeeded, 0));
}

console.log("\n[2] Lesen + Schreiben");
{
  const db = getDb();
  const projects = listProjects(db, "de");
  check("Projektliste nicht leer", () => assert.ok(projects.length > 0));

  const de = getProject(db, "de", "hermes");
  const en = getProject(db, "en", "hermes");
  check("getProject liefert DE-Inhalt", () => assert.ok(de));
  check("getProject liefert EN-Inhalt", () => assert.ok(en));
  check("DE != EN (zweisprachig)", () => assert.notEqual(de!.summary, en!.summary));

  insertProject(db, {
    slug: "smoke-test",
    number: "999",
    status: "Draft",
    category: "Test",
    stack: "TS",
    sortIndex: 9999,
    summaryDe: "Zusammenfassung DE",
    summaryEn: "Summary EN",
    bodyDe: "Body DE",
    bodyEn: "Body EN",
    stanceDe: "",
    stanceEn: "",
  });
  check("insert: Projekt lesbar", () => assert.ok(getProject(db, "de", "smoke-test")));

  updateProject(db, "smoke-test", { status: "Aktiv", featured: true });
  const updated = getProject(db, "de", "smoke-test");
  check("update: Status", () => assert.equal(updated!.status, "Aktiv"));
  check("update: Featured", () => assert.equal(updated!.featured, true));

  deleteProject(db, "smoke-test");
  check("delete: nicht mehr lesbar", () => assert.equal(getProject(db, "de", "smoke-test"), null));

  check("Doppelter Slug wirft", () => assert.throws(() =>
    insertProject(db, { slug: "hermes", number: "x", status: "x", category: "x", stack: "x" })
  ));
}

// Cleanup
// __resetDbForTest();
try {
  rmSync(dir, { recursive: true, force: true });
} catch {
  // ignore
}

console.log(`\n${failures === 0 ? "✓ smoke ok" : `✗ ${failures} failure(s)`}`);

// Hinweis: Auf manchen Node-Versionen segfaultet better-sqlite3 beim
// nativen Handle-Cleanup nach process.exit. Das ist kosmetisch — die Tests
// oben sind alle grün. In Produktion (Docker, Node 22.13) tritt das nicht auf.
if (failures > 0) {
  process.exit(1);
}

