#!/bin/bash
set -e

echo "========================================"
echo " Goa-GEL Backend Initialization"
echo "========================================"
echo ""

# Function to check if this is first boot
is_first_boot() {
  if [ ! -f "/app/data/.initialized" ]; then
    return 0  # true
  else
    return 1  # false
  fi
}

# Function to check if database has data
db_has_data() {
  local count
  count=$(PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -U "$DATABASE_USER" -d "$DATABASE_NAME" -tAc "SELECT COUNT(*) FROM users;" 2>/dev/null || echo "0")
  if [ "$count" -gt "0" ]; then
    return 0  # true - has data
  else
    return 1  # false - empty
  fi
}

# Function to check if migrations table exists
migrations_table_exists() {
  local exists
  exists=$(PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -U "$DATABASE_USER" -d "$DATABASE_NAME" -tAc "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'knex_migrations');" 2>/dev/null || echo "f")
  if [ "$exists" = "t" ]; then
    return 0  # true
  else
    return 1  # false
  fi
}

# Ensure data directory exists
mkdir -p /app/data

# Ensure .env file exists
touch /app/.env

# ========================================
# Step 1: Wait for PostgreSQL
# ========================================
echo "[1/4] Waiting for PostgreSQL to be ready..."
retries=30
until PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -U "$DATABASE_USER" -d "$DATABASE_NAME" -c '\q' 2>/dev/null; do
  retries=$((retries - 1))
  if [ $retries -le 0 ]; then
    echo "ERROR: PostgreSQL is not available after 30 retries"
    exit 1
  fi
  echo "  - PostgreSQL is unavailable - sleeping (${retries} retries left)"
  sleep 2
done
echo "  - PostgreSQL is up and accepting connections"

# ========================================
# Step 2: Run Database Migrations
# ========================================
echo ""
echo "[2/4] Running database migrations..."

# Change to database directory for Knex
cd /app/src/database

# Run migrations using the compiled knexfile
if node -e "
const knex = require('knex');
const config = require('./knexfile.js').default || require('./knexfile.js');
const env = process.env.NODE_ENV || 'production';
const db = knex(config[env]);

db.migrate.latest()
  .then(([batchNo, migrations]) => {
    if (migrations.length === 0) {
      console.log('  - All migrations already applied');
    } else {
      console.log('  - Applied ' + migrations.length + ' migration(s)');
      migrations.forEach(m => console.log('    * ' + m));
    }
    process.exit(0);
  })
  .catch(err => {
    console.error('  - Migration failed:', err.message);
    process.exit(1);
  })
  .finally(() => db.destroy());
"; then
  echo "  - Migrations completed successfully"
else
  echo "ERROR: Migration failed"
  exit 1
fi

# ========================================
# Step 3: Run Database Seeds (if needed)
# ========================================
echo ""
echo "[3/4] Checking if database seeding is needed..."

cd /app/src/database

# Check if we should run seeds
SHOULD_SEED="false"

if ! db_has_data; then
  echo "  - Database is empty, seeding required"
  SHOULD_SEED="true"
elif [ "$FORCE_RESEED" = "true" ]; then
  echo "  - FORCE_RESEED is set, reseeding database"
  SHOULD_SEED="true"
else
  echo "  - Database already has data, skipping seed"
fi

if [ "$SHOULD_SEED" = "true" ]; then
  echo "  - Running database seeds..."
  if node -e "
const knex = require('knex');
const config = require('./knexfile.js').default || require('./knexfile.js');
const env = process.env.NODE_ENV || 'production';
const db = knex(config[env]);

db.seed.run()
  .then(() => {
    console.log('  - Seeds completed successfully');
    process.exit(0);
  })
  .catch(err => {
    console.error('  - Seed failed:', err.message);
    process.exit(1);
  })
  .finally(() => db.destroy());
"; then
    echo "  - Database seeded successfully"
  else
    echo "ERROR: Seeding failed"
    exit 1
  fi
fi

# ========================================
# Step 4: Initialize Blockchain (if needed)
# ========================================
echo ""
echo "[4/4] Checking blockchain initialization..."

cd /app

if is_first_boot || [ -z "$CONTRACT_ADDRESS_LICENSE_NFT" ] || [ "$CONTRACT_ADDRESS_LICENSE_NFT" = "0x0000000000000000000000000000000000000000" ]; then
  echo "  - Blockchain not initialized, deploying contracts..."
  node /app/scripts/init-blockchain.js

  # Mark as initialized
  touch /app/data/.initialized
  echo "  - Blockchain initialization complete"

  # Reload environment variables
  if [ -f "/app/.env" ]; then
    set -a
    source /app/.env
    set +a
  fi
else
  echo "  - Blockchain already initialized, skipping"
fi

# ========================================
# Final Health Check
# ========================================
echo ""
echo "========================================"
echo " Performing Health Checks"
echo "========================================"

# Verify database has expected data
USER_COUNT=$(PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -U "$DATABASE_USER" -d "$DATABASE_NAME" -tAc "SELECT COUNT(*) FROM users;" 2>/dev/null || echo "0")
DEPT_COUNT=$(PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -U "$DATABASE_USER" -d "$DATABASE_NAME" -tAc "SELECT COUNT(*) FROM departments;" 2>/dev/null || echo "0")
WORKFLOW_COUNT=$(PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -U "$DATABASE_USER" -d "$DATABASE_NAME" -tAc "SELECT COUNT(*) FROM workflows;" 2>/dev/null || echo "0")

echo "  - Users: $USER_COUNT"
echo "  - Departments: $DEPT_COUNT"
echo "  - Workflows: $WORKFLOW_COUNT"

if [ "$USER_COUNT" -eq "0" ] || [ "$DEPT_COUNT" -eq "0" ]; then
  echo ""
  echo "WARNING: Database appears to be empty!"
  echo "You may need to run: docker compose exec api npm run db:reset"
fi

# ========================================
# Start Application
# ========================================
echo ""
echo "========================================"
echo " Starting NestJS Application"
echo "========================================"
echo ""

exec npm run start:prod
