/**
 * Database Test Helpers
 * Utilities for setting up and tearing down test database
 */

// Import models and sequelize
const { sequelize, models } = require('../../models');

/**
 * Setup test database
 * Creates test database connection and syncs models
 * @returns {Promise<void>}
 */
const setupTestDb = async () => {
  // Check if in test environment
  if (process.env.NODE_ENV !== 'test') {
    throw new Error('setupTestDb can only be used in test environment'); // Throw error if not in test environment
  }
  
  // Sync all models (force: true to drop and recreate tables)
  await sequelize.sync({ force: true }); // Sync models with force option
};

/**
 * Cleanup test database
 * Closes database connection
 * @returns {Promise<void>}
 */
const cleanupTestDb = async () => {
  // Close database connection
  await sequelize.close(); // Close sequelize connection
};

/**
 * Clear all tables
 * Deletes all data from all tables (without dropping tables)
 * @returns {Promise<void>}
 */
const clearTables = async () => {
  // Get all model names
  const modelNames = Object.keys(models); // Get model names from models object
  
  // Delete all records from each model (in reverse order to respect foreign keys)
  const reverseOrder = [
    'SystemLog',
    'ReturnItem',
    'Return',
    'FiscalReceipt',
    'Payment',
    'SaleItem',
    'Sale',
    'InventoryMovement',
    'InventoryItem',
    'Inventory',
    'ProductionOrder',
    'BOMItem',
    'BOM',
    'GRNItem',
    'GRN',
    'PurchaseOrder',
    'Vendor',
    'ProductPrice',
    'PriceList',
    'ProductVariant',
    'ProductCategory',
    'Product',
    'Category',
    'TaxExemption',
    'TaxCategory',
    'TaxRate',
    'DiscountRule',
    'Discount',
    'CashCount',
    'Shift',
    'Customer',
    'User',
  ]; // Reverse order for deletion
  
  // Delete in reverse order
  for (const modelName of reverseOrder) {
    // Check if model exists
    if (models[modelName]) {
      // Delete all records (truncate)
      await models[modelName].destroy({
        where: {},
        truncate: true, // Use truncate for faster deletion
        cascade: true, // Cascade delete related records
      }); // Delete all records
    }
  }
};

/**
 * Transaction helper
 * Runs a function within a transaction and rolls back
 * @param {Function} fn - Function to run in transaction
 * @returns {Promise<*>} Result of function
 */
const withTransaction = async (fn) => {
  // Start transaction
  const transaction = await sequelize.transaction(); // Create transaction
  
  try {
    // Run function with transaction
    const result = await fn(transaction); // Execute function with transaction
    
    // Rollback transaction (don't commit in tests)
    await transaction.rollback(); // Rollback transaction
    
    // Return result
    return result; // Return result
  } catch (error) {
    // Rollback on error
    await transaction.rollback(); // Rollback transaction on error
    
    // Re-throw error
    throw error; // Re-throw error
  }
};

// Export helpers
module.exports = {
  setupTestDb,
  cleanupTestDb,
  clearTables,
  withTransaction,
};

