import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { fileURLToPath } from 'node:url'

import { closeDb, query, withTransaction } from './client.js'

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

export async function runDatabaseMigrations() {
  const files = fs.readdirSync(MIGRATIONS_DIR)
    .filter((name) => name.endsWith('.sql'))
    .sort()

  await query(`
    CREATE TABLE IF NOT EXISTS schema_migrations (
      id BIGSERIAL PRIMARY KEY,
      filename TEXT NOT NULL UNIQUE,
      applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
    )
  `)

  const appliedRows = await query('SELECT filename FROM schema_migrations')
  const applied = new Set(appliedRows.rows.map((row) => String(row.filename)))

  for (const filename of files) {
    if (applied.has(filename)) {
      continue
    }

    const sql = fs.readFileSync(path.join(MIGRATIONS_DIR, filename), 'utf8')
    await withTransaction(async (client) => {
      await client.query(sql)
      await client.query(
        'INSERT INTO schema_migrations (filename, applied_at) VALUES ($1, NOW())',
        [filename],
      )
    })
  }
}

const currentFilePath = fileURLToPath(import.meta.url)

if (process.argv[1] && path.resolve(process.argv[1]) === currentFilePath) {
  runDatabaseMigrations()
    .then(async () => {
      await closeDb()
    })
    .catch(async (error) => {
      console.error(error)
      await closeDb()
      process.exit(1)
    })
}
