import pg from 'pg';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const MIGRATIONS_DIR = path.join(__dirname, '../migrations');

async function connectWithRetry(connStr, maxAttempts = 12) {
  for (let i = 1; i <= maxAttempts; i++) {
    const client = new pg.Client({ connectionString: connStr });
    try {
      await client.connect();
      return client;
    } catch (err) {
      await client.end().catch(() => {});
      if (i === maxAttempts) throw err;
      const delay = Math.min(2000 * i, 30000);
      console.log(`[migrate] DB not ready (attempt ${i}/${maxAttempts}), retry in ${delay}ms — ${err.message}`);
      await new Promise(r => setTimeout(r, delay));
    }
  }
}

async function run() {
  const client = await connectWithRetry(process.env.DATABASE_URL);

  await client.query(`
    CREATE TABLE IF NOT EXISTS schema_migrations (
      version    TEXT PRIMARY KEY,
      applied_at TIMESTAMPTZ NOT NULL DEFAULT now()
    )
  `);

  const { rows } = await client.query(
    'SELECT version FROM schema_migrations ORDER BY version'
  );
  const applied = new Set(rows.map(r => r.version));

  const files = fs.readdirSync(MIGRATIONS_DIR)
    .filter(f => f.endsWith('.sql'))
    .sort();

  let count = 0;
  for (const file of files) {
    if (applied.has(file)) continue;

    console.log(`[migrate] applying ${file}`);
    const sql = fs.readFileSync(path.join(MIGRATIONS_DIR, file), 'utf8');

    await client.query('BEGIN');
    try {
      await client.query(sql);
      await client.query(
        'INSERT INTO schema_migrations (version) VALUES ($1)', [file]
      );
      await client.query('COMMIT');
      console.log(`[migrate] ok ${file}`);
      count++;
    } catch (err) {
      await client.query('ROLLBACK');
      console.error(`[migrate] FAILED ${file}: ${err.message}`);
      throw err;
    }
  }

  if (count === 0) console.log('[migrate] nothing to apply');
  await client.end();
}

run().catch(err => {
  console.error('[migrate] fatal:', err.message);
  process.exit(1);
});
