/**
 * Database connection module with SQLite support
 * Uses better-sqlite3 for synchronous operations
 * Note: SQLCipher support requires special compilation, using AES-256-GCM encryption at field level instead
 */

const Database = require('better-sqlite3');
const path = require('path');
const fs = require('fs');

let db = null;
let dbPath = null;

/**
 * Initialize database connection
 * @param {string} databasePath - Path to the database file
 * @param {Object} options - Database options
 * @returns {Database} Database instance
 */
function initDatabase(databasePath, options = {}) {
  if (db) {
    return db;
  }

  dbPath = databasePath;
  
  // Ensure database directory exists
  const dbDir = path.dirname(databasePath);
  if (!fs.existsSync(dbDir)) {
    fs.mkdirSync(dbDir, { recursive: true });
  }

  // Initialize database with options
  const dbOptions = {
    fileMustExist: false,
    timeout: options.timeout || 5000,
  };
  
  // Add verbose if it's a function
  if (options.verbose && typeof options.verbose === 'function') {
    dbOptions.verbose = options.verbose;
  }

  db = new Database(databasePath, dbOptions);

  // Enable WAL mode for better concurrency
  if (options.walMode !== false) {
    db.pragma('journal_mode = WAL');
  }

  // Set reasonable defaults
  db.pragma('synchronous = NORMAL');
  db.pragma('cache_size = -64000'); // 64MB cache
  db.pragma('temp_store = MEMORY');
  db.pragma('foreign_keys = ON');

  console.log('✅ Database connected:', databasePath);
  
  return db;
}

/**
 * Get database instance
 * @returns {Database|null} Database instance or null if not initialized
 */
function getDatabase() {
  return db;
}

/**
 * Close database connection
 */
function closeDatabase() {
  if (db) {
    try {
      db.close();
      console.log('✅ Database connection closed');
    } catch (error) {
      console.error('Error closing database:', error);
    } finally {
      db = null;
      dbPath = null;
    }
  }
}

/**
 * Check if database is initialized
 * @returns {boolean}
 */
function isDatabaseInitialized() {
  return db !== null && db.open;
}

/**
 * Get database path
 * @returns {string|null}
 */
function getDatabasePath() {
  return dbPath;
}

/**
 * Create a backup of the database
 * @param {string} backupPath - Path to backup file
 * @returns {Promise<void>}
 */
async function backupDatabase(backupPath) {
  if (!db) {
    throw new Error('Database not initialized');
  }

  return new Promise((resolve, reject) => {
    try {
      const backup = db.backup(backupPath);
      backup.step(-1); // Copy all pages at once
      backup.finish();
      console.log('✅ Database backup created:', backupPath);
      resolve();
    } catch (error) {
      reject(error);
    }
  });
}

/**
 * Execute a transaction
 * @param {Function} fn - Function to execute in transaction
 * @returns {*} Result of the function
 */
function transaction(fn) {
  if (!db) {
    throw new Error('Database not initialized');
  }
  return db.transaction(fn)();
}

module.exports = {
  initDatabase,
  getDatabase,
  closeDatabase,
  isDatabaseInitialized,
  getDatabasePath,
  backupDatabase,
  transaction
};
