/**
 * Discount Controllers
 * Request handlers for discount operations
 */

// Import discount service functions
const discountService = require('../services');
// Import async handler wrapper
const asyncHandler = require('../../../middlewares/asyncHandler');
// Import response helpers
const { success: successResponse } = require('../../../utils/response');
// Import logger
const logger = require('../../../utils/logger');

// ============================================
// Discount Controllers
// ============================================

/**
 * Create discount
 * Creates a new discount with optional rules
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const createDiscount = asyncHandler(async (req, res) => {
  // Extract discount data from request body
  const { rules, ...discountData } = req.body; // Get discount data and rules separately
  
  // Create discount using service
  const discount = await discountService.createDiscount(discountData, rules || []); // Create discount
  
  // Log discount creation
  logger.info('Discount created', {
    discountId: discount.id,
    name: discount.name,
    code: discount.code,
  });
  
  // Return success response with discount data
  return successResponse(res, discount, 'Discount created successfully', 201); // Return success response
});

/**
 * Get discount by ID
 * Retrieves a discount with details
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const getDiscount = asyncHandler(async (req, res) => {
  // Extract discount ID from request params
  const { id } = req.params; // Get discount ID
  
  // Get discount using service
  const discount = await discountService.getDiscount(parseInt(id)); // Get discount
  
  // Return success response with discount data
  return successResponse(res, discount, 'Discount retrieved successfully'); // Return success response
});

/**
 * Get discount by code
 * Retrieves a discount by code
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const getDiscountByCode = asyncHandler(async (req, res) => {
  // Extract discount code from request params
  const { code } = req.params; // Get discount code
  
  // Get discount using service
  const discount = await discountService.getDiscountByCode(code); // Get discount by code
  
  // Return success response with discount data
  return successResponse(res, discount, 'Discount retrieved successfully'); // Return success response
});

/**
 * Update discount
 * Updates an existing discount
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const updateDiscount = asyncHandler(async (req, res) => {
  // Extract discount ID from request params
  const { id } = req.params; // Get discount ID
  // Extract update data from request body
  const updateData = req.body; // Get update data
  
  // Update discount using service
  const discount = await discountService.updateDiscount(parseInt(id), updateData); // Update discount
  
  // Log discount update
  logger.info('Discount updated', {
    discountId: id,
    updateData,
  });
  
  // Return success response with updated discount data
  return successResponse(res, discount, 'Discount updated successfully'); // Return success response
});

/**
 * Delete discount
 * Deletes a discount
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const deleteDiscount = asyncHandler(async (req, res) => {
  // Extract discount ID from request params
  const { id } = req.params; // Get discount ID
  
  // Delete discount using service
  await discountService.deleteDiscount(parseInt(id)); // Delete discount
  
  // Log discount deletion
  logger.info('Discount deleted', {
    discountId: id,
  });
  
  // Return success response
  return successResponse(res, null, 'Discount deleted successfully'); // Return success response
});

/**
 * List discounts
 * Lists discounts with optional filters
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const listDiscounts = asyncHandler(async (req, res) => {
  // Extract query parameters
  const { active, discount_type, search, page, limit } = req.query; // Get query params
  
  // Build filters object
  const filters = {
    ...(active !== undefined && { active: active === 'true' }), // Add active filter if provided
    ...(discount_type && { discount_type }), // Add discount_type filter if provided
    ...(search && { search }), // Add search filter if provided
  }; // Build filters
  
  // Build pagination object
  const pagination = {
    ...(page && { page }), // Add page if provided
    ...(limit && { limit }), // Add limit if provided
  }; // Build pagination
  
  // List discounts using service
  const result = await discountService.listDiscounts(filters, pagination); // List discounts
  
  // Return success response with discounts and pagination
  return successResponse(res, result, 'Discounts retrieved successfully'); // Return success response
});

/**
 * Validate discount
 * Validates if a discount can be applied
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const validateDiscount = asyncHandler(async (req, res) => {
  // Extract discount code or ID from request body
  const { discount_code, discount_id, customer_id } = req.body; // Get discount code/ID and customer ID
  
  // Get discount by code or ID
  let discount; // Initialize discount variable
  if (discount_code) {
    discount = await discountService.getDiscountByCode(discount_code); // Get by code
  } else if (discount_id) {
    discount = await discountService.getDiscount(parseInt(discount_id)); // Get by ID
  } else {
    throw new Error('Either discount_code or discount_id is required'); // Throw error if neither provided
  }
  
  // Validate discount using service
  const validation = await discountService.validateDiscount(discount, customer_id || null); // Validate discount
  
  // Return success response with validation result
  return successResponse(res, validation, validation.isValid ? 'Discount is valid' : 'Discount is invalid'); // Return success response
});

/**
 * Apply discount
 * Applies a discount to sale items (preview calculation)
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const applyDiscount = asyncHandler(async (req, res) => {
  // Extract discount code or ID and sale items from request body
  const { discount_code, discount_id, sale_items, customer_id } = req.body; // Get discount code/ID, items, and customer ID
  
  // Get discount by code or ID
  let discount; // Initialize discount variable
  if (discount_code) {
    discount = await discountService.getDiscountByCode(discount_code); // Get by code
  } else if (discount_id) {
    discount = await discountService.getDiscount(parseInt(discount_id)); // Get by ID
  } else {
    throw new Error('Either discount_code or discount_id is required'); // Throw error if neither provided
  }
  
  // Validate sale items
  if (!sale_items || !Array.isArray(sale_items) || sale_items.length === 0) {
    throw new Error('sale_items array is required'); // Throw error if items missing
  }
  
  // Apply discount using service
  const result = await discountService.applyDiscount(discount, sale_items, customer_id || null); // Apply discount
  
  // Return success response with discount application result
  return successResponse(res, result, 'Discount applied successfully'); // Return success response
});

// ============================================
// Discount Rule Controllers
// ============================================

/**
 * Create discount rule
 * Creates a new discount rule
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const createDiscountRule = asyncHandler(async (req, res) => {
  // Extract discount ID from request params
  const { discountId } = req.params; // Get discount ID
  // Extract rule data from request body
  const ruleData = req.body; // Get rule data
  
  // Create discount rule using service
  const rule = await discountService.createDiscountRule(parseInt(discountId), ruleData); // Create rule
  
  // Log rule creation
  logger.info('Discount rule created', {
    ruleId: rule.id,
    discountId,
  });
  
  // Return success response with rule data
  return successResponse(res, rule, 'Discount rule created successfully', 201); // Return success response
});

/**
 * Get discount rule by ID
 * Retrieves a discount rule
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const getDiscountRule = asyncHandler(async (req, res) => {
  // Extract rule ID from request params
  const { ruleId } = req.params; // Get rule ID
  
  // Get discount rule using service
  const rule = await discountService.getDiscountRule(parseInt(ruleId)); // Get rule
  
  // Return success response with rule data
  return successResponse(res, rule, 'Discount rule retrieved successfully'); // Return success response
});

/**
 * Update discount rule
 * Updates an existing discount rule
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const updateDiscountRule = asyncHandler(async (req, res) => {
  // Extract rule ID from request params
  const { ruleId } = req.params; // Get rule ID
  // Extract update data from request body
  const updateData = req.body; // Get update data
  
  // Update discount rule using service
  const rule = await discountService.updateDiscountRule(parseInt(ruleId), updateData); // Update rule
  
  // Log rule update
  logger.info('Discount rule updated', {
    ruleId,
    updateData,
  });
  
  // Return success response with updated rule data
  return successResponse(res, rule, 'Discount rule updated successfully'); // Return success response
});

/**
 * Delete discount rule
 * Deletes a discount rule
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const deleteDiscountRule = asyncHandler(async (req, res) => {
  // Extract rule ID from request params
  const { ruleId } = req.params; // Get rule ID
  
  // Delete discount rule using service
  await discountService.deleteDiscountRule(parseInt(ruleId)); // Delete rule
  
  // Log rule deletion
  logger.info('Discount rule deleted', {
    ruleId,
  });
  
  // Return success response
  return successResponse(res, null, 'Discount rule deleted successfully'); // Return success response
});

/**
 * List discount rules
 * Lists discount rules for a discount
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const listDiscountRules = asyncHandler(async (req, res) => {
  // Extract discount ID from request params
  const { discountId } = req.params; // Get discount ID
  
  // List discount rules using service
  const rules = await discountService.listDiscountRules(parseInt(discountId)); // List rules
  
  // Return success response with rules
  return successResponse(res, rules, 'Discount rules retrieved successfully'); // Return success response
});

/**
 * Get discounts for product
 * Returns all discounts available for a specific product
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 */
const getDiscountsForProduct = asyncHandler(async (req, res) => {
  // Extract product ID from request params
  const { productId } = req.params;

  // Get discounts for product using service
  const discounts = await discountService.getDiscountsForProduct(parseInt(productId));

  // Return success response with discounts
  return successResponse(res, { discounts }, 'Discounts retrieved successfully');
});

// Export all controllers
module.exports = {
  // Discount controllers
  createDiscount,
  getDiscount,
  getDiscountByCode,
  updateDiscount,
  deleteDiscount,
  listDiscounts,
  validateDiscount,
  applyDiscount,
  getDiscountsForProduct,
  // Discount rule controllers
  createDiscountRule,
  getDiscountRule,
  updateDiscountRule,
  deleteDiscountRule,
  listDiscountRules,
};

