/**
 * Sales Management Controllers
 * Request handlers for sales and POS management endpoints
 */

// Import sales service
const salesService = require('../services');
// Import stock checking service
const stockCheckingService = require('../../inventory/services/stockChecking');
// Import dispatch service
const dispatchService = require('../services/dispatch');
// 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');

/**
 * Create sale controller
 * Handles sale creation
 * POST /api/sales
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const createSale = asyncHandler(async (req, res) => {
  // Extract sale data from request body
  const saleData = req.body; // Sale data
  const userId = req.user.id; // Current user ID (from auth middleware)
  
  // Call sales service to create sale
  const result = await salesService.createSale(saleData, userId); // Create sale
  
  // Log sale creation to system logs
  await SystemLog.create({
    user_id: userId, // Current user ID
    action: 'CREATE_SALE', // Action type
    entity: 'Sale', // Entity type
    entity_id: result.sale.id, // Created sale ID
    payload: { invoice_no: result.sale.invoice_no, total: result.sale.total }, // Log payload
  });
  
  // Log sale creation
  logger.info(`Sale created: ${result.sale.invoice_no}`, {
    createdBy: userId,
    saleId: result.sale.id,
    total: result.sale.total,
  });
  
  // Return success response with created sale
  return res.status(201).json({
    success: true, // Indicate success
    message: 'Sale created successfully', // Success message
    data: result, // Sale with items
  });
});

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

/**
 * List sales controller
 * Handles listing sales with pagination and filters
 * GET /api/sales
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const listSales = asyncHandler(async (req, res) => {
  // Extract query parameters
  const {
    page,
    limit,
    customer_id,
    status,
    sale_type,
    start_date,
    end_date,
    user_id,
    invoice_no, // Invoice number search
  } = req.query; // Extract query parameters
  
  // Build options object
  const options = {
    page, // Page number
    limit, // Items per page
    customerId: customer_id ? parseInt(customer_id) : null, // Customer ID filter
    status, // Status filter
    saleType: sale_type, // Sale type filter
    startDate: start_date, // Start date filter
    endDate: end_date, // End date filter
    userId: user_id ? parseInt(user_id) : null, // User ID filter
    invoice_no, // Invoice number search filter
  };
  
  // Call sales service to list sales
  const result = await salesService.listSales(options); // Get sales list
  
  // Return success response with sales list
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Sales retrieved successfully', // Success message
    data: result, // Sales list and pagination
  });
});

/**
 * Cancel sale controller
 * Handles sale cancellation
 * PUT /api/sales/:id/cancel
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const cancelSale = asyncHandler(async (req, res) => {
  // Extract sale ID from request parameters
  const saleId = parseInt(req.params.id); // Sale ID from URL
  const userId = req.user.id; // Current user ID (from auth middleware)
  
  // Call sales service to cancel sale
  const sale = await salesService.cancelSale(saleId, userId); // Cancel sale
  
  // Log sale cancellation to system logs
  await SystemLog.create({
    user_id: userId, // Current user ID
    action: 'CANCEL_SALE', // Action type
    entity: 'Sale', // Entity type
    entity_id: sale.id, // Cancelled sale ID
    payload: { invoice_no: sale.invoice_no }, // Log payload
  });
  
  // Log sale cancellation
  logger.info(`Sale cancelled: ${sale.invoice_no}`, {
    cancelledBy: userId,
    saleId: sale.id,
  });
  
  // Return success response with cancelled sale
  return res.status(200).json({
    success: true, // Indicate success
    message: 'Sale cancelled successfully', // Success message
    data: { sale }, // Cancelled sale data
  });
});

/**
 * Check stock for multiple items controller
 * Handles bulk stock availability checking for cart items
 * POST /api/sales/check-stock
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const checkStock = asyncHandler(async (req, res) => {
  // Extract items array from request body
  const { items } = req.body;

  if (!Array.isArray(items) || items.length === 0) {
    return res.status(400).json({
      success: false,
      message: 'Items array is required and cannot be empty',
    });
  }

  // Call stock checking service to bulk check stock
  const results = await stockCheckingService.bulkCheckStock(items);

  // Return success response with stock check results
  return res.status(200).json({
    success: true,
    message: 'Stock checked successfully',
    data: { results },
  });
});

/**
 * Dispatch sale controller
 * Handles dispatching a sale (removing items from inventory)
 * POST /api/sales/:id/dispatch
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const dispatchSale = asyncHandler(async (req, res) => {
  const saleId = parseInt(req.params.id); // Extract sale ID from URL params
  const userId = req.user.id; // Current user ID (from auth middleware)

  // Call dispatch service to dispatch sale
  const result = await dispatchService.dispatchSale(saleId, userId);

  // Log dispatch action to system logs
  await SystemLog.create({
    user_id: userId,
    action: 'DISPATCH_SALE',
    entity: 'Sale',
    entity_id: saleId,
    payload: { dispatchedAt: result.dispatchedAt, itemsProcessed: result.itemsProcessed },
  });

  // Log dispatch action
  logger.info(`Sale ${saleId} dispatched by user ${userId}`, {
    saleId,
    userId,
    dispatchedAt: result.dispatchedAt,
    itemsProcessed: result.itemsProcessed,
  });

  // Return success response
  return res.status(200).json({
    success: true,
    message: 'Sale dispatched successfully',
    data: result,
  });
});

// Export controller functions
module.exports = {
  createSale, // Create sale controller
  getSale, // Get sale by ID controller
  listSales, // List sales controller
  cancelSale, // Cancel sale controller
  checkStock, // Check stock controller
  dispatchSale, // Dispatch sale controller
};
