#!/usr/bin/env node
/**
 * import-dev-seed.mjs
 *
 * Imports packages/db/prisma/dev-seed.sql into the local dev database.
 * Wipes the public schema, re-applies the current Prisma schema, loads the
 * seed data, then sets every user's password to "Dev123456!" via argon2id.
 *
 * Usage:
 *   node scripts/import-dev-seed.mjs
 *
 * Requirements:
 *   - The capakraken-postgres-1 Docker container must be running
 *   - DATABASE_URL must point to a local capakraken database
 *   - dev-seed.sql must exist (run export-dev-seed.mjs first)
 */

import { execSync, spawnSync } from "node:child_process";
import { existsSync, readFileSync } from "node:fs";
import { resolve } from "node:path";
import { loadWorkspaceEnv, resolveRealWorkspaceRoot } from "./load-env.mjs";

loadWorkspaceEnv();
const workspaceRoot = resolveRealWorkspaceRoot();

// ── Safety check ─────────────────────────────────────────────────────────────

const rawUrl = process.env["DATABASE_URL"];
if (!rawUrl) {
  console.error("❌  DATABASE_URL is not set.");
  process.exit(1);
}

let parsedUrl;
try {
  parsedUrl = new URL(rawUrl);
} catch {
  console.error("❌  DATABASE_URL is not a valid URL.");
  process.exit(1);
}

const host = parsedUrl.hostname;
if (!["localhost", "127.0.0.1", "::1"].includes(host)) {
  console.error(`❌  Refusing to import into non-local host: ${host}`);
  console.error("    import-dev-seed is only for local development databases.");
  process.exit(1);
}

const DB_USER = decodeURIComponent(parsedUrl.username) || "capakraken";
const DB_NAME = parsedUrl.pathname.replace(/^\/+/, "") || "capakraken";
const DB_PORT = parsedUrl.port || "5432";

// ── Docker container check ────────────────────────────────────────────────────

const CONTAINER = "capakraken-postgres-1";
const containerCheck = spawnSync("docker", ["inspect", "--format={{.State.Running}}", CONTAINER], {
  encoding: "utf8",
});
if (containerCheck.stdout.trim() !== "true") {
  console.error(`❌  Container ${CONTAINER} is not running.`);
  console.error("    Start it with: docker compose up -d postgres");
  process.exit(1);
}

// ── Check seed file exists ────────────────────────────────────────────────────

const seedPath = resolve(workspaceRoot, "packages/db/prisma/dev-seed.sql");
if (!existsSync(seedPath)) {
  console.error("❌  packages/db/prisma/dev-seed.sql not found.");
  console.error("    Generate it first with: node scripts/export-dev-seed.mjs");
  process.exit(1);
}

console.log(`🗑   Wiping public schema in ${DB_USER}@${host}:${DB_PORT}/${DB_NAME} …`);

// ── Drop and recreate the public schema ──────────────────────────────────────

function psql(sql) {
  const result = spawnSync(
    "docker",
    ["exec", "-i", CONTAINER, "psql", "-U", DB_USER, "-d", DB_NAME, "-c", sql],
    { encoding: "utf8" },
  );
  if (result.status !== 0) {
    console.error("❌  psql command failed:");
    console.error(result.stderr);
    process.exit(1);
  }
  return result.stdout;
}

psql("DROP SCHEMA public CASCADE; CREATE SCHEMA public;");

// ── Push current Prisma schema ────────────────────────────────────────────────

console.log("🔧  Applying current Prisma schema (db push) …");
try {
  execSync("pnpm db:push", {
    cwd: workspaceRoot,
    stdio: "inherit",
    env: { ...process.env },
  });
} catch {
  console.error("❌  pnpm db:push failed. See output above.");
  process.exit(1);
}

// ── Import the seed SQL ───────────────────────────────────────────────────────

console.log("📥  Importing dev-seed.sql …");

const importResult = spawnSync(
  "docker",
  ["exec", "-i", CONTAINER, "psql", "-U", DB_USER, "-d", DB_NAME],
  {
    encoding: "utf8",
    input: readFileSync(seedPath, "utf8"),
    maxBuffer: 256 * 1024 * 1024,
  },
);

if (importResult.status !== 0) {
  console.error("❌  psql import failed:");
  console.error(importResult.stderr);
  process.exit(1);
}

// ── Hash dev password and update all users ────────────────────────────────────

console.log("🔐  Setting dev passwords (Dev123456!) …");

const { hash } = await import("@node-rs/argon2");
const devHash = await hash("Dev123456!", {
  memoryCost: 19456,
  timeCost: 2,
  outputLen: 32,
  parallelism: 1,
});

const updateResult = spawnSync(
  "docker",
  [
    "exec",
    "-i",
    CONTAINER,
    "psql",
    "-U", DB_USER,
    "-d", DB_NAME,
    "-c", `UPDATE users SET "passwordHash" = '${devHash}';`,
  ],
  { encoding: "utf8" },
);

if (updateResult.status !== 0) {
  console.error("❌  Password update failed:");
  console.error(updateResult.stderr);
  process.exit(1);
}

// ── Summary ───────────────────────────────────────────────────────────────────

const userCount = psql(`SELECT COUNT(*) FROM users;`)
  .trim()
  .split("\n")
  .find((line) => /^\s*\d+\s*$/.test(line))
  ?.trim() ?? "?";

console.log();
console.log("✅  Dev seed imported successfully.");
console.log(`    Users: ${userCount}`);
console.log("    Password for all accounts: Dev123456!");
console.log("    Sign in at: http://localhost:3100/auth/signin");
console.log();
console.log("Note: TOTP is disabled for all users. Re-enable via Settings if needed.");
