#!/usr/bin/env node
/**
 * Setup database script
 * Initializes the SQLite database with the schema
 */

const fs = require('fs');
const path = require('path');
const { initDatabase, getDatabase, closeDatabase } = require('../src/database/connection');
const { initEncryption } = require('../src/utils/encryption');
const { DB_PATH, KEY_FILE } = require('../src/database/config');
const crypto = require('crypto');

const DATABASE_PATH = DB_PATH;
const DATABASE_ENCRYPTION_KEY = process.env.DATABASE_ENCRYPTION_KEY;
const WAL_MODE = process.env.DATABASE_WAL_MODE !== '0' && process.env.DATABASE_WAL_MODE !== 'false';
const DATABASE_USE_SQLCIPHER = process.env.DATABASE_USE_SQLCIPHER !== '0' && process.env.DATABASE_USE_SQLCIPHER !== 'false';

async function setupDatabase() {
  console.log('🔧 Setting up database...');
  console.log('  Database path:', DATABASE_PATH);
  
  // Ensure data directory exists
  const dataDir = path.dirname(DATABASE_PATH);
  if (!fs.existsSync(dataDir)) {
    fs.mkdirSync(dataDir, { recursive: true });
    console.log('  Created data directory:', dataDir);
  }
  
  let encryptionKey = DATABASE_ENCRYPTION_KEY;

  // Check if encryption key is provided
  if (!encryptionKey) {
    if (fs.existsSync(KEY_FILE)) {
      encryptionKey = fs.readFileSync(KEY_FILE, 'utf8').trim();
      if (encryptionKey) {
        process.env.DATABASE_ENCRYPTION_KEY = encryptionKey;
        console.log('✅ Loaded encryption key from file');
      }
    }
  }

  if (!encryptionKey) {
    console.warn('⚠️  WARNING: No DATABASE_ENCRYPTION_KEY found!');
    console.warn('⚠️  Generating a random key for this session (not persistent).');
    console.warn('⚠️  For production, set DATABASE_ENCRYPTION_KEY environment variable.');
    console.warn('⚠️  Generate one with: openssl rand -hex 32');
    const generatedKey = crypto.randomBytes(32).toString('hex');
    process.env.DATABASE_ENCRYPTION_KEY = generatedKey;
    encryptionKey = generatedKey;
    try {
      const keyDir = path.dirname(KEY_FILE);
      if (!fs.existsSync(keyDir)) fs.mkdirSync(keyDir, { recursive: true });
      fs.writeFileSync(KEY_FILE, generatedKey, { mode: 0o600 });
      console.log('⚠️  Saved generated key to:', KEY_FILE);
    } catch (err) {
      console.warn('⚠️  Failed to persist encryption key:', err.message);
    }
    console.log('✅ Generated temporary encryption key');
  } else {
    console.log('✅ Using encryption key from environment');
  }
  
  // Initialize encryption
  try {
    initEncryption(encryptionKey);
    console.log('✅ Encryption initialized');
  } catch (error) {
    console.error('❌ Failed to initialize encryption:', error.message);
    process.exit(1);
  }
  
  // Initialize database
  try {
    initDatabase(DATABASE_PATH, {
      verbose: false,
      walMode: WAL_MODE,
      sqlcipherKey: DATABASE_USE_SQLCIPHER ? encryptionKey : null,
      cipherCompatibility: process.env.DATABASE_CIPHER_COMPAT || 4,
      kdfIter: process.env.DATABASE_KDF_ITER || 64000
    });
    console.log('✅ Database initialized');
  } catch (error) {
    console.error('❌ Failed to initialize database:', error.message);
    process.exit(1);
  }
  
  // Load and execute schema
  try {
    const schemaPath = path.join(__dirname, '..', 'src', 'database', 'schema.sql');
    const schema = fs.readFileSync(schemaPath, 'utf8');
    
    const db = getDatabase();
    
    // Execute the entire schema as one block
    // SQLite can handle multiple statements with exec()
    db.exec(schema);

    // Add missing columns if this is an upgraded database
    const userColumns = db.prepare('PRAGMA table_info(users)').all();
    const userColumnNames = new Set(userColumns.map((c) => c.name));
    if (!userColumnNames.has('data')) {
      db.exec('ALTER TABLE users ADD COLUMN data TEXT');
      console.log('✅ Added users.data column');
    }

    console.log('✅ Database schema created');
  } catch (error) {
    console.error('❌ Failed to create schema:', error.message);
    closeDatabase();
    process.exit(1);
  }
  
  // Verify tables
  try {
    const db = getDatabase();
    const tables = db.prepare(`
      SELECT name FROM sqlite_master 
      WHERE type='table' AND name NOT LIKE 'sqlite_%'
      ORDER BY name
    `).all();
    
    console.log('✅ Database tables created:');
    tables.forEach(table => {
      console.log(`  - ${table.name}`);
    });
  } catch (error) {
    console.error('❌ Failed to verify tables:', error.message);
  }
  
  // Close database
  closeDatabase();
  
  console.log('');
  console.log('✅ Database setup complete!');
  console.log('');
  console.log('Next steps:');
  console.log('  1. Run migration: node scripts/migrate-to-database.js');
  console.log('  2. Verify migration: node scripts/verify-migration.js');
  console.log('  3. Switch to database mode: unset USE_JSON_DATABASE');
  console.log('  4. Start server: npm start');
}

// Run setup
setupDatabase().catch(error => {
  console.error('❌ Setup failed:', error);
  process.exit(1);
});
