/**
 * Wipe all data from the database, preserving schema + drizzle migration
 * history. Run before swapping seed fixtures.
 *
 *   pnpm tsx scripts/db-reset.ts          (refuses without --confirm)
 *   pnpm tsx scripts/db-reset.ts --confirm
 *
 * Truncates every table in the `public` schema except the drizzle
 * migration tracker, then resets sequences. Wraps the loop in a single
 * transaction so a mid-wipe failure rolls back cleanly.
 *
 * Refuses to run when DATABASE_URL points at anything that doesn't look
 * like a local/dev host. Override with --i-know-what-im-doing.
 */

import 'dotenv/config';
import postgres from 'postgres';

const url: string = process.env.DATABASE_URL ?? '';
if (!url) {
  console.error('DATABASE_URL is not set; aborting.');
  process.exit(1);
}

const args = new Set(process.argv.slice(2));
if (!args.has('--confirm')) {
  console.error('Refusing to wipe without --confirm');
  console.error('Run again as: pnpm tsx scripts/db-reset.ts --confirm');
  process.exit(1);
}

// Best-effort safety: refuse for anything that doesn't look like a local DB.
function looksLocal(u: string): boolean {
  try {
    const parsed = new URL(u);
    return (
      parsed.hostname === 'localhost' ||
      parsed.hostname === '127.0.0.1' ||
      parsed.hostname === '::1' ||
      parsed.hostname.endsWith('.local') ||
      parsed.hostname.endsWith('.internal') ||
      parsed.hostname === 'host.docker.internal' ||
      // Docker compose service names commonly used here
      parsed.hostname === 'postgres' ||
      parsed.hostname === 'db'
    );
  } catch {
    return false;
  }
}

if (!looksLocal(url) && !args.has('--i-know-what-im-doing')) {
  console.error(
    `DATABASE_URL host doesn't look local. Refusing to wipe a remote DB without --i-know-what-im-doing.`,
  );
  process.exit(1);
}

const sql = postgres(url, { max: 1 });

async function main() {
  console.log('Resetting database...');
  console.log(`  url: ${url.replace(/:[^:@]*@/, ':***@')}`);

  const tables = await sql<{ tablename: string }[]>`
    SELECT tablename FROM pg_tables
    WHERE schemaname = 'public'
      AND tablename NOT LIKE 'drizzle_%'
      AND tablename != '__drizzle_migrations'
  `;

  if (tables.length === 0) {
    console.log('  no user tables found, nothing to do.');
    await sql.end();
    return;
  }

  // Single TRUNCATE … CASCADE is faster than per-table loops and handles
  // FK ordering for us. Quote table names defensively.
  const tableList = tables.map((t) => `"public"."${t.tablename}"`).join(', ');

  console.log(`  truncating ${tables.length} tables...`);
  await sql.unsafe(`TRUNCATE ${tableList} RESTART IDENTITY CASCADE`);
  console.log('  done.');

  await sql.end();
  console.log('');
  console.log('Database reset complete. Run a seed script next:');
  console.log('  pnpm db:seed              # realistic NocoDB-shaped fixture');
  console.log('  pnpm db:seed:synthetic    # one client per pipeline stage');
}

main().catch(async (err) => {
  console.error('Reset failed:', err);
  await sql.end().catch(() => undefined);
  process.exit(1);
});
