/**
 * Product Management Controllers
 * Request handlers for product management endpoints
 */

// Import product service
const productService = require('../services');
// Import stock checking service
const stockCheckingService = require('../../inventory/services/stockChecking');
// 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');
// Import path for file path manipulation
const path = require('path');

/**
 * Create product controller
 * Handles product creation
 * POST /api/products
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const createProduct = asyncHandler(async (req, res) => {
  // Extract product data from request body
  const productData = req.body;
  
  // Handle image upload if file exists
  if (req.file) {
    // Store image path relative to uploads directory
    productData.image_url = `/uploads/products/${req.file.filename}`; // Image URL path
  }
  
  // Call product service to create product
  const result = await productService.createProduct(productData);
  
  // Log product creation to system logs
  await SystemLog.create({
    user_id: req.user.id, // Current user ID (from auth middleware)
    action: 'CREATE_PRODUCT', // Action type
    entity: 'Product', // Entity type
    entity_id: result.product.id, // Created product ID
    payload: { name: result.product.name, sku: result.product.sku }, // Log payload
  });
  
  // Log product creation
  logger.info(`Product created: ${result.product.name}`, {
    createdBy: req.user.id,
    productId: result.product.id,
  });
  
  // Return success response with created product data
  return res.status(201).json({
    success: true, // Indicate success
    message: 'Product created successfully', // Success message
    data: { product: result }, // Product data
  });
});

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

/**
 * Get product availability controller
 * Handles retrieving stock availability for a product
 * GET /api/products/:id/availability?variant_id=2
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const getProductAvailability = asyncHandler(async (req, res) => {
  // Extract product ID from request parameters
  const productId = parseInt(req.params.id);
  
  // Call stock checking service to get availability
  const availability = await stockCheckingService.getProductAvailability(productId, null);
  
  // Return success response with availability data
  return res.status(200).json({
    success: true,
    message: 'Product availability retrieved successfully',
    data: availability,
  });
});

/**
 * Update product controller
 * Handles product updates
 * PUT /api/products/:id
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const updateProduct = asyncHandler(async (req, res) => {
  // Extract product ID from request parameters
  const productId = parseInt(req.params.id);
  // Extract update data from request body
  const updateData = req.body;
  
  // Handle image upload if file exists
  if (req.file) {
    // Store image path relative to uploads directory
    updateData.image_url = `/uploads/products/${req.file.filename}`; // Image URL path
  }
  
  // Call product service to update product
  const product = await productService.updateProduct(productId, updateData);
  
  // Log product update to system logs
  await SystemLog.create({
    user_id: req.user.id, // Current user ID (from auth middleware)
    action: 'UPDATE_PRODUCT', // Action type
    entity: 'Product', // Entity type
    entity_id: product.id, // Updated product ID
    payload: { updated_fields: Object.keys(updateData) }, // Log payload
  });
  
  // Log product update
  logger.info(`Product updated: ${product.name}`, {
    updatedBy: req.user.id,
    productId: product.id,
  });
  
  // Return success response with updated product data
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Product updated successfully', // Success message
    data: { product }, // Updated product data
  });
});

/**
 * Delete product controller
 * Handles product deletion (not actually deleted, kept for audit)
 * DELETE /api/products/:id
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const deleteProduct = asyncHandler(async (req, res) => {
  // Extract product ID from request parameters
  const productId = parseInt(req.params.id);
  
  // Call product service to delete product
  // Note: deleteProduct throws ValidationError - products are not deleted for audit purposes
  await productService.deleteProduct(productId);
  
  // This code won't be reached if deleteProduct throws an error
  // But keeping it here for future implementation
});

/**
 * List products controller
 * Handles listing products with pagination and filters
 * GET /api/products
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const listProducts = asyncHandler(async (req, res) => {
  // Extract query parameters
  const { 
    page, 
    limit, 
    search, 
    product_type, 
    track_inventory, 
    category_id,
    ids, // NEW: Filter by product IDs (array or comma-separated)
    include, // NEW: Comma-separated list (e.g., 'prices,inventory')
    price_list_id, // NEW: Price list ID for pricing
    quantity, // NEW: Quantity for quantity-based pricing
  } = req.query;
  
  // Parse ids parameter (handle both array and comma-separated string)
  let idsArray = [];
  if (ids) {
    if (Array.isArray(ids)) {
      // If ids is already an array (from ids[]=3 format)
      idsArray = ids.map(id => parseInt(id)).filter(id => !isNaN(id) && id > 0);
    } else if (typeof ids === 'string') {
      // If ids is a string (from ids=3,4,5 format)
      idsArray = ids.split(',').map(id => parseInt(id.trim())).filter(id => !isNaN(id) && id > 0);
    }
  }
  
  // Parse include parameter (handle both array and comma-separated string)
  let includeArray = [];
  if (include) {
    if (Array.isArray(include)) {
      // If include is already an array (from include[]=prices format)
      includeArray = include.map(item => String(item).trim()).filter(Boolean);
    } else if (typeof include === 'string') {
      // If include is a string (from include=prices,inventory format)
      includeArray = include.split(',').map(item => item.trim()).filter(Boolean);
    }
  }
  
  // Call product service to list products
  const result = await productService.listProducts({
    page,
    limit,
    search,
    product_type,
    track_inventory,
    category_id,
    ids: idsArray.length > 0 ? idsArray : null, // Pass as array or null
    include: includeArray, // Pass as array
    price_list_id: price_list_id ? parseInt(price_list_id) : null,
    quantity: quantity ? parseFloat(quantity) : 1,
  });
  
  // Return success response with products list and pagination info
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Products retrieved successfully', // Success message
    data: result, // Products list and pagination
  });
});

/**
 * Search products controller
 * Handles product search
 * GET /api/products/search?q=searchTerm
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const searchProducts = asyncHandler(async (req, res) => {
  // Extract search term from query parameters
  const searchTerm = req.query.q || req.query.search;
  // Extract limit from query parameters
  const limit = req.query.limit;
  
  // Call product service to search products
  const products = await productService.searchProducts(searchTerm, { limit });
  
  // Return success response with search results
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Products search completed', // Success message
    data: { products }, // Search results
  });
});

/**
 * Upload product image controller
 * Handles product image upload
 * POST /api/products/:id/image
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const uploadProductImage = asyncHandler(async (req, res) => {
  // Extract product ID from request parameters
  const productId = parseInt(req.params.id);
  
  // Check if file was uploaded
  if (!req.file) {
    return res.status(400).json({
      success: false, // Indicate failure
      message: 'No image file provided', // Error message
    });
  }
  
  // Prepare update data with image URL
  const updateData = {
    image_url: `/uploads/products/${req.file.filename}`, // Image URL path
  };
  
  // Call product service to update product with image URL
  const product = await productService.updateProduct(productId, updateData);
  
  // Log product image upload to system logs
  await SystemLog.create({
    user_id: req.user.id, // Current user ID (from auth middleware)
    action: 'UPLOAD_PRODUCT_IMAGE', // Action type
    entity: 'Product', // Entity type
    entity_id: product.id, // Product ID
    payload: { image_url: product.image_url }, // Log payload
  });
  
  // Log product image upload
  logger.info(`Product image uploaded: ${product.name}`, {
    uploadedBy: req.user.id,
    productId: product.id,
    imageUrl: product.image_url,
  });
  
  // Return success response with updated product data
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Product image uploaded successfully', // Success message
    data: { 
      product,
      image_url: product.image_url, // Image URL
      filename: req.file.filename, // Uploaded filename
    },
  });
});

// Export controller functions
module.exports = {
  getProductAvailability, // Get product availability
  createProduct, // Create product controller
  getProductById, // Get product by ID controller
  updateProduct, // Update product controller
  deleteProduct, // Delete product controller
  listProducts, // List products controller
  searchProducts, // Search products controller
  uploadProductImage, // Upload product image controller
};
