/**
 * Inventory Management Controllers
 * Request handlers for inventory management endpoints
 */

// Import inventory service
const inventoryService = require('../services');
// Import async handler wrapper
const asyncHandler = require('../../../middlewares/asyncHandler');
// Import logger for logging
const logger = require('../../../utils/logger');
// Import SystemLog model for audit trail
const { SystemLog } = require('../../../models');

/**
 * Get inventory quantity controller
 * Handles retrieving inventory quantity for a product
 * GET /api/inventory/quantity?product_id=1
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const getQuantity = asyncHandler(async (req, res) => {
  // Extract product ID from query parameters (variants removed)
  const productId = parseInt(req.query.product_id); // Product ID from query
  
  // Call inventory service to get quantity
  const quantity = await inventoryService.getQuantity(productId); // Get inventory quantity
  
  // Return success response with quantity
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Inventory quantity retrieved successfully', // Success message
    data: {
      product_id: productId, // Product ID
      // variant_id removed
      quantity, // Current quantity
    },
  });
});

/**
 * Check availability controller
 * Handles checking if product is available in stock
 * GET /api/inventory/check-availability?product_id=1&quantity=10
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const checkAvailability = asyncHandler(async (req, res) => {
  // Extract parameters from query
  const productId = parseInt(req.query.product_id); // Product ID from query
const requiredQuantity = parseFloat(req.query.quantity); // Required quantity from query
  
  // Call inventory service to check availability
  const isAvailable = await inventoryService.checkAvailability(productId, requiredQuantity); // Check stock availability
  
  // Return success response with availability status
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Availability checked successfully', // Success message
    data: {
      product_id: productId, // Product ID
      // variant_id removed
      required_quantity: requiredQuantity, // Required quantity
      available: isAvailable, // Availability status
    },
  });
});

/**
 * Get inventory record controller
 * Handles retrieving inventory record with product details
 * GET /api/inventory/:productId
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const getInventory = asyncHandler(async (req, res) => {
  // Extract product ID from request parameters
  const productId = parseInt(req.params.productId); // Product ID from URL
  // Call inventory service to get inventory record
  const inventory = await inventoryService.getInventory(productId); // Get inventory record
  
  // Return success response with inventory data
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Inventory retrieved successfully', // Success message
    data: { inventory }, // Inventory record with details
  });
});

/**
 * List inventory controller
 * Handles listing inventory with filters and pagination
 * GET /api/inventory?page=1&limit=10&product_id=1&low_stock=true
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const listInventory = asyncHandler(async (req, res) => {
  // Extract query parameters
  const {
    page: pageParam,
    limit: limitParam,
    product_id,
    low_stock,
    out_of_stock,
    product_type,
  } = req.query;
  
  // Parse pagination parameters with defaults
  const page = pageParam ? parseInt(pageParam, 10) : 1;
  const limit = limitParam ? parseInt(limitParam, 10) : 10;
  
  // Build options object
  const options = {
    page, // Page number
    limit, // Items per page
    productId: product_id ? parseInt(product_id, 10) : null, // Product ID filter
    // variantId removed
    lowStock: low_stock === 'true', // Low stock filter
    outOfStock: out_of_stock === 'true', // Out of stock filter
    product_type: product_type || null, // Product type filter (RM or FG)
  };
  
  // If low stock filter is requested, use getLowStockItems
  if (options.lowStock) {
    // Call inventory service to get low stock items
    const result = await inventoryService.getLowStockItems(options); // Get low stock items
    
    // Return success response with low stock items
    return res.status(200).json({
      success: true, // Indicate success
      message: 'Low stock items retrieved successfully', // Success message
      data: result, // Low stock items and pagination
    });
  }
  
  // Otherwise, use regular listInventory
  // Call inventory service to list inventory
  const result = await inventoryService.listInventory(options); // Get inventory list
  
  // Return success response with inventory list
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Inventory list retrieved successfully', // Success message
    data: result, // Inventory list and pagination
  });
});

/**
 * Adjust inventory quantity controller
 * Handles inventory quantity adjustments (increase/decrease)
 * POST /api/inventory/adjust
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const adjustInventory = asyncHandler(async (req, res) => {
  // Extract adjustment data from request body
  const { product_id, quantity_change, reason, reference_id } = req.body; // Extract adjustment data
  
  // Call inventory service to adjust quantity
  const inventory = await inventoryService.adjustQuantity(
    parseInt(product_id), // Product ID
    parseFloat(quantity_change), // Quantity change
    reason, // Movement reason
    // variant_id removed
    reference_id ? parseInt(reference_id) : null, // Reference ID (optional)
    req.user.id // Current user ID (from auth middleware)
  );
  
  // Log inventory adjustment to system logs
  await SystemLog.create({
    user_id: req.user.id, // Current user ID (from auth middleware)
    action: 'ADJUST_INVENTORY', // Action type
    entity: 'Inventory', // Entity type
    entity_id: inventory.id, // Inventory ID
    payload: { product_id, quantity_change, reason, new_quantity: inventory.quantity }, // Log payload
  });
  
  // Log inventory adjustment
  logger.info(`Inventory adjusted: product_id=${product_id}, change=${quantity_change}`, {
    adjustedBy: req.user.id,
    inventoryId: inventory.id,
    quantityChange: quantity_change,
  });
  
  // Return success response with updated inventory
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Inventory adjusted successfully', // Success message
    data: { inventory }, // Updated inventory record
  });
});

/**
 * Set inventory quantity controller
 * Handles setting inventory to a specific quantity (absolute value)
 * PUT /api/inventory/set-quantity
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const setInventoryQuantity = asyncHandler(async (req, res) => {
  // Extract data from request body
  const { product_id, quantity, notes } = req.body; // Extract set quantity data
  
  // Call inventory service to set quantity
  const inventory = await inventoryService.setQuantity(
    parseInt(product_id), // Product ID
    parseFloat(quantity), // New quantity
    // variant_id removed
    req.user.id, // Current user ID (from auth middleware)
    notes // Additional notes (optional)
  );
  
  // Log inventory quantity set to system logs
  await SystemLog.create({
    user_id: req.user.id, // Current user ID (from auth middleware)
    action: 'SET_INVENTORY_QUANTITY', // Action type
    entity: 'Inventory', // Entity type
    entity_id: inventory.id, // Inventory ID
    payload: { product_id, quantity, notes }, // Log payload
  });
  
  // Log inventory quantity set
  logger.info(`Inventory quantity set: product_id=${product_id}, quantity=${quantity}`, {
    setBy: req.user.id,
    inventoryId: inventory.id,
    quantity,
  });
  
  // Return success response with updated inventory
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Inventory quantity set successfully', // Success message
    data: { inventory }, // Updated inventory record
  });
});

/**
 * Set reorder level controller
 * Handles setting reorder level for a product
 * PUT /api/inventory/reorder-level
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const setReorderLevel = asyncHandler(async (req, res) => {
  // Extract data from request body
  
  // Call inventory service to set reorder level
  const inventory = await inventoryService.setReorderLevel(
    parseInt(product_id), // Product ID
    parseFloat(reorder_level), // New reorder level
  );
  
  // Log reorder level set to system logs
  await SystemLog.create({
    user_id: req.user.id, // Current user ID (from auth middleware)
    action: 'SET_REORDER_LEVEL', // Action type
    entity: 'Inventory', // Entity type
    entity_id: inventory.id, // Inventory ID
    payload: { product_id, reorder_level }, // Log payload
  });
  
  // Log reorder level set
  logger.info(`Reorder level set: product_id=${product_id}, reorder_level=${reorder_level}`, {
    setBy: req.user.id,
    inventoryId: inventory.id,
    reorderLevel: reorder_level,
  });
  
  // Return success response with updated inventory
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Reorder level set successfully', // Success message
    data: { inventory }, // Updated inventory record
  });
});

/**
 * Get inventory movements controller
 * Handles retrieving inventory movement history for a product
 * GET /api/inventory/:productId/movements&page=1&limit=20
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const getInventoryMovements = asyncHandler(async (req, res) => {
  // Extract product ID from request parameters
  const productId = parseInt(req.params.productId); // Product ID from URL
  // Extract pagination parameters
  const { page, limit } = req.query; // Extract pagination parameters
  
  // Build options object
  const options = {
    page, // Page number
    limit, // Items per page
  };
  
  // Call inventory service to get movements
  const result = await inventoryService.getInventoryMovements(productId, options); // Get inventory movements
  
  // Return success response with movements
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Inventory movements retrieved successfully', // Success message
    data: result, // Movements and pagination
  });
});

// Import inventory items controllers
const inventoryItemsControllers = require('./items');
// Import reconciliation controllers
const reconciliationControllers = require('./reconciliation');

// Export controller functions (quantity-based + UID-based + reconciliation)
module.exports = {
  // Quantity-based inventory controllers
  getQuantity, // Get inventory quantity controller
  checkAvailability, // Check availability controller
  getInventory, // Get inventory record controller
  listInventory, // List inventory controller
  adjustInventory, // Adjust inventory quantity controller
  setInventoryQuantity, // Set inventory quantity controller
  setReorderLevel, // Set reorder level controller
  getInventoryMovements, // Get inventory movements controller
  // UID-based inventory item controllers
  createInventoryItem: inventoryItemsControllers.createInventoryItem,
  getInventoryItemByUID: inventoryItemsControllers.getInventoryItemByUID,
  updateInventoryItemStatus: inventoryItemsControllers.updateInventoryItemStatus,
  scanInventoryItem: inventoryItemsControllers.scanInventoryItem,
  listInventoryItems: inventoryItemsControllers.listInventoryItems,
  // Reconciliation controllers
  getReconciliationReport: reconciliationControllers.getReconciliationReport,
  checkDiscrepancies: reconciliationControllers.checkDiscrepancies,
  autoReconcile: reconciliationControllers.autoReconcile,
};
