#!/usr/bin/env node
/**
 * scripts/migrate-auth-v1.mjs — Auth v1 one-shot migration.
 *
 * Idempotent: safe to run multiple times. On re-runs, all INSERTs are
 * OR IGNORE so no duplicate rows are created.
 *
 * Steps:
 *   1. Verify organizations table exists (aborts if schema not applied yet).
 *   2. INSERT OR IGNORE personal-org row.
 *   3. INSERT OR IGNORE local-user-1 row.
 *   4. INSERT OR IGNORE owner membership for local-user-1 in personal-org.
 *   5. UPDATE projects SET org_id = 'personal-org' WHERE org_id IS NULL.
 *   6. UPDATE artifacts SET sharing_scope = 'private' WHERE sharing_scope IS NULL.
 *   7. Write marker data/.auth-migrated-v1 and exit 0.
 *
 * Usage:
 *   node scripts/migrate-auth-v1.mjs
 *   MADARX_OWNER_EMAIL=you@company.com node scripts/migrate-auth-v1.mjs
 */

import { DatabaseSync } from 'node:sqlite';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const here = path.dirname(fileURLToPath(import.meta.url));
const ROOT = path.resolve(here, '..');

const DATA_DIR = (process.env.MADARX_DATA_DIR || process.env.VILLA515_DATA_DIR)
  ? path.resolve(process.env.MADARX_DATA_DIR || process.env.VILLA515_DATA_DIR)
  : process.env.MADARX_HOME
    ? path.join(path.resolve(process.env.MADARX_HOME), 'data')
    : path.join(ROOT, 'data');

const DB_FILE = path.join(DATA_DIR, 'madarx.sqlite');
const MARKER = path.join(DATA_DIR, '.auth-migrated-v1');

function nowIso() {
  return new Date().toISOString();
}

/**
 * Core migration logic. Accepts an open DatabaseSync instance so it can be
 * called both from this CLI script and from lib/seeds.js (passing getDb()).
 *
 * @param {DatabaseSync} db
 * @returns {{ projectsUpdated: number, artifactsUpdated: number }}
 */
export function runAuthV1Migration(db) {
  // ── Step 1: Verify schema is applied ───────────────────────────────────────
  const tableExists = db
    .prepare(
      "SELECT name FROM sqlite_master WHERE type='table' AND name='organizations' LIMIT 1"
    )
    .get();
  if (!tableExists) {
    throw new Error(
      '[migrate-auth-v1] organizations table does not exist. ' +
      'The schema has not been applied yet. Start the app once to initialize the schema, ' +
      'then re-run this migration.'
    );
  }

  const ownerEmail = process.env.MADARX_OWNER_EMAIL || 'owner@local.dev';
  const now = nowIso();

  // ── Step 2: INSERT OR IGNORE personal-org ──────────────────────────────────
  db.prepare(
    `INSERT OR IGNORE INTO organizations (id, slug, name, plan, created_at, updated_at)
     VALUES ('personal-org', 'personal', 'Personal Org', 'free', ?, ?)`
  ).run(now, now);

  // ── Step 3: INSERT OR IGNORE local-user-1 ─────────────────────────────────
  db.prepare(
    `INSERT OR IGNORE INTO users (id, email, display_name, auth_provider, created_at)
     VALUES ('local-user-1', ?, 'Local Owner', 'local', ?)`
  ).run(ownerEmail, now);

  // ── Step 4: INSERT OR IGNORE ownership membership ─────────────────────────
  db.prepare(
    `INSERT OR IGNORE INTO org_memberships (id, org_id, user_id, role, accepted_at)
     VALUES ('mem-local-owner', 'personal-org', 'local-user-1', 'owner', ?)`
  ).run(now);

  // ── Step 5: Bind orphaned projects to personal-org ────────────────────────
  const projectsResult = db
    .prepare("UPDATE projects SET org_id = 'personal-org' WHERE org_id IS NULL")
    .run();

  // ── Step 6: Default artifacts sharing_scope to 'private' ─────────────────
  // The ALTER TABLE added DEFAULT 'private' but pre-ALTER rows may have NULL.
  const artifactsResult = db
    .prepare("UPDATE artifacts SET sharing_scope = 'private' WHERE sharing_scope IS NULL")
    .run();

  return {
    projectsUpdated: projectsResult.changes,
    artifactsUpdated: artifactsResult.changes,
  };
}

// ── CLI entry point ───────────────────────────────────────────────────────────
// ESM direct-run guard: only execute main() when this file is the entry point,
// not when imported as a module (e.g. by lib/seeds.js).

async function main() {
  // Check marker file.
  if (fs.existsSync(MARKER)) {
    console.log('[migrate-auth-v1] Marker file exists — migration already applied. Re-running for idempotency check.');
  }

  if (!fs.existsSync(DB_FILE)) {
    console.error(
      '[migrate-auth-v1] Database file not found at ' + DB_FILE + '. ' +
      'Start the app once to create it, then re-run this script.'
    );
    process.exit(1);
  }

  const db = new DatabaseSync(DB_FILE);
  db.exec('PRAGMA journal_mode=WAL;');
  db.exec('PRAGMA foreign_keys=ON;');

  try {
    const result = runAuthV1Migration(db);

    // ── Step 7: Write marker ────────────────────────────────────────────────
    fs.writeFileSync(MARKER, 'migrated at ' + new Date().toISOString() + '\n', 'utf8');

    const ownerEmail = process.env.MADARX_OWNER_EMAIL || 'owner@local.dev';
    console.log('[migrate-auth-v1] Migration complete.');
    console.log('  personal-org: ensured');
    console.log('  local-user-1: ensured (email: ' + ownerEmail + ')');
    console.log('  owner membership: ensured');
    console.log('  projects bound: ' + result.projectsUpdated);
    console.log('  artifacts defaulted: ' + result.artifactsUpdated);
    console.log('  marker: ' + MARKER);
  } catch (err) {
    console.error('[migrate-auth-v1] ERROR:', err.message);
    process.exit(1);
  } finally {
    try { db.close(); } catch {}
  }
}

// Only run when executed directly: `node scripts/migrate-auth-v1.mjs`
// ESM equivalent of CommonJS `if (require.main === module)`.
const _thisFile = fileURLToPath(import.meta.url);
const _entryFile = process.argv[1] ? path.resolve(process.argv[1]) : null;
if (_entryFile === _thisFile) {
  main();
}
