#!/usr/bin/env node

const { Client } = require('pg');
const { DataSource } = require('typeorm');
const path = require('path');
const { spawn } = require('child_process');

async function waitForPostgres(maxAttempts = 30) {
  console.log('⏳ Waiting for PostgreSQL to be ready...');

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      const client = new Client({
        host: process.env.DATABASE_HOST,
        port: parseInt(process.env.DATABASE_PORT, 10),
        user: process.env.DATABASE_USER,
        password: process.env.DATABASE_PASSWORD,
        database: process.env.DATABASE_NAME,
      });

      await client.connect();
      await client.end();
      console.log('✅ PostgreSQL is ready');
      return true;
    } catch (error) {
      console.log(`⏳ Attempt ${attempt}/${maxAttempts} - PostgreSQL not ready, retrying...`);
      await new Promise(resolve => setTimeout(resolve, 2000));
    }
  }

  console.error('❌ Failed to connect to PostgreSQL after', maxAttempts, 'attempts');
  process.exit(1);
}

async function runMigrations() {
  console.log('🔄 Running database migrations...');

  const AppDataSource = new DataSource({
    type: 'postgres',
    host: process.env.DATABASE_HOST,
    port: parseInt(process.env.DATABASE_PORT, 10),
    username: process.env.DATABASE_USER,
    password: process.env.DATABASE_PASSWORD,
    database: process.env.DATABASE_NAME,
    entities: [path.join(__dirname, 'dist/**/*.orm-entity.js')],
    migrations: [path.join(__dirname, 'dist/infrastructure/persistence/typeorm/migrations/*.js')],
    synchronize: false,
    logging: true,
  });

  try {
    await AppDataSource.initialize();
    console.log('✅ DataSource initialized');

    const migrations = await AppDataSource.runMigrations();

    if (migrations.length === 0) {
      console.log('✅ No pending migrations');
    } else {
      console.log(`✅ Successfully ran ${migrations.length} migration(s):`);
      migrations.forEach(migration => {
        console.log(`   - ${migration.name}`);
      });
    }

    await AppDataSource.destroy();
    console.log('✅ Database migrations completed');
    return true;
  } catch (error) {
    console.error('❌ Error during migration:', error);
    process.exit(1);
  }
}

function startApplication() {
  console.log('🚀 Starting NestJS application...');

  const app = spawn('node', ['dist/main'], {
    stdio: 'inherit',
    env: process.env,
  });

  app.on('exit', code => {
    process.exit(code);
  });

  process.on('SIGTERM', () => app.kill('SIGTERM'));
  process.on('SIGINT', () => app.kill('SIGINT'));
}

async function main() {
  console.log('🚀 Starting Xpeditis Backend...');

  await waitForPostgres();
  await runMigrations();
  startApplication();
}

main().catch(error => {
  console.error('❌ Startup failed:', error);
  process.exit(1);
});
