#!/usr/bin/env node
/**
 * Dev-DB runner for the EDR freight database. psql is NOT installed on this
 * machine; this is the sanctioned way to query, EXPLAIN-validate, and inspect
 * the remote dev DB. Resolves `pg` from apps/edr-freight-api so it runs from
 * anywhere in the repo.
 *
 *   node .claude/skills/edr-db/query.cjs "SELECT ... "        run SQL (console.table)
 *   node .claude/skills/edr-db/query.cjs explain "SELECT..."  EXPLAIN-validate only
 *   node .claude/skills/edr-db/query.cjs columns <table>      list freight.<table> columns
 *   node .claude/skills/edr-db/query.cjs migrations [like]    public.migrations rows
 *   node .claude/skills/edr-db/query.cjs drift <table>        columns vs entity check helper
 *
 * Connection: DB_HOST/DB_PORT/DB_USER/DB_PASSWORD/DB_NAME env vars, falling
 * back to the shared dev database.
 */
const path = require('path');
const { createRequire } = require('module');

const repoRoot = path.resolve(__dirname, '..', '..', '..');
const apiRequire = createRequire(
  path.join(repoRoot, 'apps', 'edr-freight-api', 'package.json'),
);
const { Client } = apiRequire('pg');

const cfg = {
  host: process.env.DB_HOST ?? '10.18.7.207',
  port: parseInt(process.env.DB_PORT ?? '5432', 10),
  user: process.env.DB_USER ?? 'postgres',
  password: process.env.DB_PASSWORD ?? 'dcba@1234',
  database: process.env.DB_NAME ?? 'edr_dev',
};

const [, , first, ...rest] = process.argv;

async function main() {
  if (!first) {
    console.error('usage: query.cjs "<sql>" | explain "<sql>" | columns <table> | migrations [like] | drift <table>');
    process.exit(2);
  }
  const c = new Client(cfg);
  await c.connect();
  try {
    if (first === 'columns') {
      const r = await c.query(
        `SELECT column_name, data_type, is_nullable, column_default
           FROM information_schema.columns
          WHERE table_schema='freight' AND table_name=$1
          ORDER BY ordinal_position`,
        [rest[0]],
      );
      console.table(r.rows);
    } else if (first === 'migrations') {
      const like = rest[0] ? `%${rest[0]}%` : '%';
      const r = await c.query(
        `SELECT id, timestamp, name FROM public.migrations
          WHERE name ILIKE $1 ORDER BY id DESC LIMIT 40`,
        [like],
      );
      console.table(r.rows);
    } else if (first === 'drift') {
      // Quick drift signal: DB columns for the table. Compare by eye against
      // the entity's @Column names; a recorded-but-absent column = drift.
      const r = await c.query(
        `SELECT column_name FROM information_schema.columns
          WHERE table_schema='freight' AND table_name=$1 ORDER BY column_name`,
        [rest[0]],
      );
      console.log(r.rows.map((x) => x.column_name).join('\n'));
    } else if (first === 'explain') {
      await c.query('EXPLAIN ' + rest.join(' '));
      console.log('OK — statement is valid against', cfg.database);
    } else {
      const sql = [first, ...rest].join(' ');
      const started = Date.now();
      const r = await c.query(sql);
      if (Array.isArray(r.rows) && r.rows.length) console.table(r.rows);
      console.log(`${r.rowCount ?? 0} row(s), ${Date.now() - started}ms`);
    }
  } finally {
    await c.end();
  }
}

main().catch((e) => {
  console.error('FAIL:', e.message);
  process.exit(1);
});
