/* eslint-disable @typescript-eslint/no-require-imports */
const fs = require('node:fs');
const path = require('node:path');
const mysql = require('mysql2/promise');

function loadRootEnv() {
  const envPath = path.resolve(__dirname, '../../../.env');
  if (!fs.existsSync(envPath)) {
    return;
  }

  const content = fs.readFileSync(envPath, 'utf8');
  for (const line of content.split(/\r?\n/)) {
    const trimmed = line.trim();
    if (!trimmed || trimmed.startsWith('#')) {
      continue;
    }
    const separatorIndex = trimmed.indexOf('=');
    if (separatorIndex === -1) {
      continue;
    }
    const key = trimmed.slice(0, separatorIndex).trim();
    const value = trimmed
      .slice(separatorIndex + 1)
      .trim()
      .replace(/^"|"$/g, '');
    process.env[key] ??= value;
  }
}

async function main() {
  loadRootEnv();

  if (!process.env.DATABASE_URL) {
    throw new Error('DATABASE_URL is required');
  }

  const connection = await mysql.createConnection(process.env.DATABASE_URL);
  const migrationsDir = path.resolve(__dirname, '../src/database/migrations');
  const files = fs
    .readdirSync(migrationsDir)
    .filter((file) => file.endsWith('.sql'))
    .sort();

  await connection.query(`
    CREATE TABLE IF NOT EXISTS schema_migrations (
      version VARCHAR(255) NOT NULL PRIMARY KEY,
      applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  `);

  for (const file of files) {
    const [rows] = await connection.query(
      'SELECT version FROM schema_migrations WHERE version = ?',
      [file],
    );
    if (rows.length > 0) {
      console.log(`skip ${file}`);
      continue;
    }

    const sql = fs.readFileSync(path.join(migrationsDir, file), 'utf8');
    await connection.beginTransaction();
    try {
      for (const statement of sql.split(/;\s*(?:\r?\n|$)/)) {
        const trimmed = statement.trim();
        if (trimmed) {
          await connection.query(trimmed);
        }
      }
      await connection.query(
        'INSERT INTO schema_migrations (version) VALUES (?)',
        [file],
      );
      await connection.commit();
      console.log(`applied ${file}`);
    } catch (error) {
      await connection.rollback();
      throw error;
    }
  }

  await connection.end();
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});
