const stockLedgerService = require('./stockLedgerService');

/**
 * Validate that issuing stock will not result in negative balance
 * 
 * @param {Object} params - Validation parameters
 * @param {Integer} params.companyId - Company ID
 * @param {Integer} params.plantId - Plant ID
 * @param {Integer} params.materialId - Material ID
 * @param {String} params.storageLocation - Storage location code (optional, null for total)
 * @param {Number} params.quantityToIssue - Quantity to issue
 * @param {String} params.operation - Operation name for error messages (e.g., 'Material Issue', 'Backflush')
 * @param {String} params.referenceNumber - Reference number for error messages (optional)
 * @param {Object} params.transaction - Sequelize transaction (optional)
 * @returns {Object} Validation result with isValid, currentBalance, availableBalance, errorMessage
 */
exports.validateStockIssue = async (params) => {
  const {
    companyId,
    plantId,
    materialId,
    storageLocation = null,
    quantityToIssue,
    operation = 'Stock Issue',
    referenceNumber = null,
    transaction = null
  } = params;

  if (!companyId || !plantId || !materialId) {
    return {
      isValid: false,
      currentBalance: 0,
      availableBalance: 0,
      errorMessage: 'Company ID, Plant ID, and Material ID are required for stock validation'
    };
  }

  const quantity = parseFloat(quantityToIssue || 0);
  if (quantity <= 0) {
    return {
      isValid: true, // Zero or negative quantity is valid (no issue)
      currentBalance: 0,
      availableBalance: 0,
      errorMessage: null
    };
  }

  try {
    // Get current stock balance
    const currentBalance = await stockLedgerService.getCurrentBalance(
      companyId,
      plantId,
      materialId,
      storageLocation,
      transaction
    );

    // Calculate available balance after issue
    const availableBalance = currentBalance - quantity;

    // Check if issue would result in negative balance
    if (availableBalance < 0) {
      const locationText = storageLocation ? ` in storage location ${storageLocation}` : '';
      const refText = referenceNumber ? ` (${referenceNumber})` : '';
      
      return {
        isValid: false,
        currentBalance,
        availableBalance,
        errorMessage: `Insufficient stock for ${operation}${refText}. Material ID: ${materialId}${locationText}. Available: ${currentBalance}, Required: ${quantity}, Shortfall: ${Math.abs(availableBalance)}`
      };
    }

    return {
      isValid: true,
      currentBalance,
      availableBalance,
      errorMessage: null
    };
  } catch (error) {
    console.error('Error validating stock issue:', error);
    return {
      isValid: false,
      currentBalance: 0,
      availableBalance: 0,
      errorMessage: `Error validating stock: ${error.message}`
    };
  }
};

/**
 * Validate multiple stock issues in batch
 * Returns first validation error found, or all validations if all pass
 * 
 * @param {Array} items - Array of items to validate
 * @param {Object} commonParams - Common parameters (companyId, plantId, operation, transaction)
 * @returns {Object} Validation result with isValid, errors array, validations array
 */
exports.validateBatchStockIssues = async (items, commonParams) => {
  const {
    companyId,
    plantId,
    operation = 'Batch Stock Issue',
    transaction = null
  } = commonParams;

  const validations = [];
  const errors = [];

  for (const item of items) {
    const validation = await exports.validateStockIssue({
      companyId,
      plantId,
      materialId: item.material_id,
      storageLocation: item.source_storage_location || item.storage_location || null,
      quantityToIssue: item.quantity,
      operation: `${operation} - ${item.material?.material_number || item.material_id || 'Material'}`,
      referenceNumber: item.reference_number || null,
      transaction
    });

    validations.push({
      item,
      validation
    });

    if (!validation.isValid) {
      errors.push({
        materialId: item.material_id,
        materialNumber: item.material?.material_number || item.material_id,
        storageLocation: item.source_storage_location || item.storage_location || null,
        quantity: item.quantity,
        currentBalance: validation.currentBalance,
        availableBalance: validation.availableBalance,
        errorMessage: validation.errorMessage
      });
    }
  }

  return {
    isValid: errors.length === 0,
    errors,
    validations
  };
};

/**
 * Validate stock before creating stock ledger entry
 * This is a wrapper that validates before creating the entry
 * 
 * @param {Object} entryData - Stock ledger entry data
 * @param {Object} transaction - Sequelize transaction (optional)
 * @returns {Object} Validation result
 */
exports.validateBeforeLedgerEntry = async (entryData, transaction = null) => {
  // Only validate for ISSUE transactions (quantity_out > 0)
  const quantityOut = parseFloat(entryData.quantity_out || 0);
  
  if (quantityOut <= 0) {
    return {
      isValid: true,
      errorMessage: null
    };
  }

  return await exports.validateStockIssue({
    companyId: entryData.company_id,
    plantId: entryData.plant_id,
    materialId: entryData.material_id,
    storageLocation: entryData.storage_location || null,
    quantityToIssue: quantityOut,
    operation: entryData.reference_type || 'Stock Issue',
    referenceNumber: entryData.reference_number || null,
    transaction
  });
};

/**
 * Get formatted error message for stock validation failures
 * 
 * @param {Array} errors - Array of validation errors from validateBatchStockIssues
 * @returns {String} Formatted error message
 */
exports.formatValidationErrors = (errors) => {
  if (!errors || errors.length === 0) {
    return 'Stock validation failed';
  }

  if (errors.length === 1) {
    return errors[0].errorMessage;
  }

  // Multiple errors - format as list
  const errorList = errors.map((err, index) => 
    `${index + 1}. Material ${err.materialNumber || err.materialId}${err.storageLocation ? ` (Location: ${err.storageLocation})` : ''}: Available ${err.currentBalance}, Required ${err.quantity}, Shortfall ${err.quantity - err.currentBalance}`
  ).join('\n');

  return `Multiple stock validation failures:\n${errorList}`;
};

