/*
 * File: src/main/java/reports/service/InventoryService.java
 * Description: This service class provides functionality for handling inventory-related operations in the ERP reporting system.
 * It includes methods for retrieving KPI data and generating inventory reports.
 */

package com.nebula.erp.reports.service;

import com.nebula.erp.reports.model.inventories.Inventory;
import com.nebula.erp.reports.repository.inventories.InventoryRepository;
import com.nebula.erp.reports.repository.inventories.StockRepository;
import com.nebula.erp.reports.repository.product.BrandRepository;
import com.nebula.erp.reports.repository.product.CategoryRepository;
import com.nebula.erp.reports.repository.product.TaxRepository;
import com.nebula.erp.reports.repository.purchase.*;
import com.nebula.erp.reports.repository.sales.PaymentRepository;
import com.nebula.erp.reports.repository.sales.SalesRepository;
import com.nebula.erp.reports.repository.sales.SalesReturnItemRepository;
import com.nebula.erp.reports.repository.sales.SalesItemRepository;
import com.nebula.erp.reports.repository.product.ProductRepository;
import com.nebula.erp.reports.requestmodel.SalesRequest;
import com.nebula.erp.reports.utility.CreateLogger;
import com.nebula.erp.reports.utility.JwtRequestUtils;
import com.nebula.erp.reports.utility.MoneyUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import com.nebula.erp.reports.utility.ApiResponseStructure;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class InventoryService {

    @Autowired
    private PurchaseRepository purchaseRepository;

    @Autowired
    private SalesRepository salesRepository;

    @Autowired
    private SalesItemRepository salesItemRepository;

    @Autowired
    private SalesReturnItemRepository salesReturnItemRepository;

    @Autowired
    private SupplierRepository supplierRepository;

    @Autowired
    private GRNRepository grnRepository;

    @Autowired
    private PurchaseReturnRepository purchaseReturnRepository;

    @Autowired
    private PurchaseReturnItemRepository purchaseReturnItemRepository;

    @Autowired
    private ProductRepository productRepository;

    @Autowired
    private GRNItemRepository grnItemRepository;

    @Autowired
    private PurchaseItemRepository purchaseItemRepository;

    @Autowired
    private CategoryRepository categoryRepository;

    @Autowired
    private TaxRepository taxRepository;

    @Autowired
    private BrandRepository brandRepository;

    @Autowired
    private PaymentRepository paymentRepository;

    @Autowired
    private InventoryRepository inventoryRepository;

    @Autowired
    private StockRepository stockRepository;

    @Autowired
    private JwtRequestUtils jwtRequestUtils;

    @Autowired
    private HttpServletRequest httpServletRequest;

    @Autowired
    private CreateLogger createLogger;

    private static final String path = "/reports/inventory";

    public ApiResponseStructure<Map<String, Object>> getKPIData(LocalDate fromDate, LocalDate toDate) {
        // Extract Authorization headers from the request
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.AUTHORIZATION, httpServletRequest.getHeader(HttpHeaders.AUTHORIZATION));

        String tenantName = jwtRequestUtils.getTenantNameFromHeaders(headers);

        if (fromDate != null && toDate != null) {
            // Convert LocalDate to LocalDateTime for comparison with created_at
            LocalDateTime fromDateTime = fromDate.atStartOfDay();
            LocalDateTime toDateTime = toDate.atTime(23, 59, 59);

            // Initialize totals
            final BigDecimal[] totalStockValue = { BigDecimal.ZERO };
            final int[] totalQuantityInStock = { 0 };
            final int[] lowStockAlerts = { 0 };
            int totalProducts = 0;
            BigDecimal averageStockValuePerProduct = BigDecimal.ZERO;

            // Fetch all inventories for the given date range
            List<Object[]> inventories = inventoryRepository.findAllInventoriesByDateRange(fromDateTime, toDateTime,
                    tenantName);

            // Loop through inventories to calculate required metrics
            inventories.forEach(inventory -> {
                Long product_id = Long.valueOf(inventory[0].toString());
                BigDecimal sellingPrice = productRepository.findSellingPriceByIdAndTenant(product_id, tenantName);
                if (sellingPrice != null) {
                    try {
                        BigDecimal stockValue = sellingPrice
                                .multiply(BigDecimal.valueOf(Long.parseLong(inventory[1].toString())));
                        totalStockValue[0] = totalStockValue[0].add(stockValue);

                        // Increment total quantity in stock
                        totalQuantityInStock[0] += Integer.valueOf(inventory[1].toString());

                        // Check for low stock alerts (example threshold of 10 units)
                        if (Integer.valueOf(inventory[1].toString()) < 10) {
                            lowStockAlerts[0]++;
                        }
                    } catch (NumberFormatException e) {
                        // Handle potential NumberFormatException here
                        System.err.println("Error parsing number: " + e.getMessage());
                    }
                }
            });

            // Count total products
            totalProducts = productRepository.countAllByTenant(fromDateTime, toDateTime, tenantName);

            // Calculate average stock value per product
            if (totalProducts > 0) {
                averageStockValuePerProduct = totalStockValue[0].divide(BigDecimal.valueOf(totalProducts),
                        RoundingMode.HALF_UP);
            }

            // Prepare response data
            Map<String, Object> kpiData = new LinkedHashMap<>();
            kpiData.put("total_stock_value", MoneyUtils.truncateToTwoDecimals(totalStockValue[0].doubleValue()));
            kpiData.put("total_quantity_in_stock", totalQuantityInStock[0]);
            kpiData.put("low_stock_alerts", lowStockAlerts[0]);
            kpiData.put("total_products", totalProducts);
            kpiData.put("average_stock_value_per_product",
                    MoneyUtils.truncateToTwoDecimals(averageStockValuePerProduct.doubleValue()));

            // Create and return the structured ApiResponseStructure
            return new ApiResponseStructure<>("Success", 200, "Data retrieved.", kpiData);
        }
        createLogger.createLogger("error", path, "GET", "Please provide start-date and end-date with valid dates.", "");
        return new ApiResponseStructure<>("Failure", 500, "Please provide start-date and end-date with valid dates.",
                Collections.emptyMap());
    }

    public ApiResponseStructure<Map<String, Object>> getInventoryReport(SalesRequest salesRequest, String reportType) {
        // Extract Authorization headers from the request
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.AUTHORIZATION, httpServletRequest.getHeader(HttpHeaders.AUTHORIZATION));

        String tenantName = jwtRequestUtils.getTenantNameFromHeaders(headers);

        // Validate presence of fromDate and toDate
        if (salesRequest.getStartDate() == null || salesRequest.getEndDate() == null) {
            createLogger.createLogger("error", path, "POST", "Both 'startDate' and 'endDate' must be provided.", "");
            return new ApiResponseStructure<>("Error", HttpStatus.BAD_REQUEST.value(),
                    "Both 'startDate' and 'endDate' must be provided.", new HashMap<>());
        }

        LocalDate fromDate = salesRequest.getStartDate();
        LocalDate toDate = salesRequest.getEndDate();

        LocalDateTime fromDateTime = fromDate.atStartOfDay();
        LocalDateTime toDateTime = toDate.atTime(23, 59, 59);

        // Create a specification for the query
        Specification<Inventory> spec = Specification.where(null);

        // Add tenant name filtering
        spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("tenant"), tenantName));

        // Add date range filtering
        spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder.between(root.get("created_at"), fromDateTime,
                toDateTime));

        // Switch cases to handle various report type
        switch (reportType) {
            case "stockLevel":
                // Add dynamic conditions
                if (salesRequest.getConditions() != null) {
                    for (SalesRequest.Condition condition : salesRequest.getConditions()) {
                        switch (condition.getOperator()) {
                            case "equals":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder
                                        .equal(root.get(condition.getField()), condition.getValue()));
                                break;
                            case "greaterThan":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder.greaterThan(
                                        root.get(condition.getField()), (Comparable) condition.getValue()));
                                break;
                            case "lessThan":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder
                                        .lessThan(root.get(condition.getField()), (Comparable) condition.getValue()));
                                break;
                            case "greaterThanOrEquals":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder.greaterThanOrEqualTo(
                                        root.get(condition.getField()), (Comparable) condition.getValue()));
                                break;
                            case "lessThanOrEquals":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder.lessThanOrEqualTo(
                                        root.get(condition.getField()), (Comparable) condition.getValue()));
                                break;
                            default:
                                createLogger.createLogger("error", path, "POST", "", "");
                                throw new IllegalArgumentException(
                                        "Operator " + condition.getOperator() + " is not supported.");
                        }
                    }
                }

                // Fetch the data with pagination for inventory
                Pageable pageable = PageRequest.of(salesRequest.getPage() != null ? salesRequest.getPage() : 0, // Page
                                                                                                                // number
                                                                                                                // is
                                                                                                                // zero-based
                        salesRequest.getSize() != null ? salesRequest.getSize() : 20);

                // Prepare response data
                List<Map<String, Object>> reportData = new ArrayList<>();
                int totalQuantity = 0;

                // Fetch all inventory items based on tenant name and date range
                Page<Inventory> inventory = inventoryRepository.findAll(spec, pageable);

                for (Inventory item : inventory) {
                    Long productId = item.getProduct_id();
                    String productName = productRepository.findProductNameById(productId, tenantName); // Fetch product
                                                                                                       // name
                    Long categoryId = productRepository.findCategoryIdByProductId(productId, tenantName); // Fetch
                                                                                                          // category ID
                    Long brandId = productRepository.findBrandIdByProductId(productId, tenantName); // Fetch brand ID
                    String categoryName = categoryRepository.findCategoryNameById(categoryId, tenantName); // Fetch
                                                                                                           // category
                                                                                                           // name
                    String brandName = brandRepository.findBrandNameById(brandId, tenantName); // Fetch brand name

                    // Convert quantity from String to int
                    int quantity = item.getTotal_quantity();

                    // Create report entry
                    Map<String, Object> reportEntry = new LinkedHashMap<>();
                    reportEntry.put("id", item.getId());
                    reportEntry.put("product_id", productId);
                    reportEntry.put("product_name", productName);
                    reportEntry.put("category_id", categoryId);
                    reportEntry.put("category_name", categoryName);
                    reportEntry.put("brand_id", brandId);
                    reportEntry.put("brand_name", brandName);
                    reportEntry.put("quantity", quantity);
                    reportEntry.put("date", String.valueOf(item.getCreated_at()));

                    reportData.add(reportEntry);

                    // Update totals
                    totalQuantity += quantity;
                }

                // Prepare column details
                Map<String, Object> column = new LinkedHashMap<>();
                column.put("id", "ID");
                column.put("product_id", "PRODUCT ID");
                column.put("product_name", "PRODUCT NAME");
                column.put("category_id", "CATEGORY ID");
                column.put("category_name", "CATEGORY NAME");
                column.put("brand_id", "BRAND ID");
                column.put("brand_name", "BRAND NAME");
                column.put("quantity", "QUANTITY");
                column.put("date", "DATE");

                // Prepare pagination details
                Map<String, Object> pagination = new LinkedHashMap<>();
                pagination.put("currentPage", inventory.getNumber() + 1); // Page number is 0-based
                pagination.put("totalPages", inventory.getTotalPages());
                pagination.put("pageSize", pageable.getPageSize());
                pagination.put("totalRecords", inventory.getTotalElements()); // Total records from the Page object

                // Prepare summary details
                Map<String, Object> summary = new LinkedHashMap<>();
                summary.put("totalQuantity", totalQuantity);
                summary.put("lowStockAlerts", calculateLowStockAlerts(inventory.getContent())); // Replace with your
                                                                                                // logic for low stock
                                                                                                // alerts

                // Prepare inventory response data
                Map<String, Object> inventoryResponseData = new LinkedHashMap<>();
                inventoryResponseData.put("module", "inventory");
                inventoryResponseData.put("reportType", reportType);
                inventoryResponseData.put("startDate", String.valueOf(fromDate));
                inventoryResponseData.put("endDate", String.valueOf(toDate));
                inventoryResponseData.put("reportData", reportData);
                inventoryResponseData.put("column", column);
                inventoryResponseData.put("pagination", pagination);
                inventoryResponseData.put("summary", summary);

                // Create and return the structured ApiResponseStructure
                return new ApiResponseStructure<>("Success", 200, "Data retrieved.", inventoryResponseData);
            case "lowStock":
                // Add dynamic conditions
                if (salesRequest.getConditions() != null) {
                    for (SalesRequest.Condition condition : salesRequest.getConditions()) {
                        switch (condition.getOperator()) {
                            case "equals":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder
                                        .equal(root.get(condition.getField()), condition.getValue()));
                                break;
                            case "greaterThan":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder.greaterThan(
                                        root.get(condition.getField()), (Comparable) condition.getValue()));
                                break;
                            case "lessThan":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder
                                        .lessThan(root.get(condition.getField()), (Comparable) condition.getValue()));
                                break;
                            case "greaterThanOrEquals":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder.greaterThanOrEqualTo(
                                        root.get(condition.getField()), (Comparable) condition.getValue()));
                                break;
                            case "lessThanOrEquals":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder.lessThanOrEqualTo(
                                        root.get(condition.getField()), (Comparable) condition.getValue()));
                                break;
                            default:
                                createLogger.createLogger("error", path, "POST", "", "");
                                throw new IllegalArgumentException(
                                        "Operator " + condition.getOperator() + " is not supported.");
                        }
                    }
                }

                // Fetch the data with pagination for inventory
                pageable = PageRequest.of(salesRequest.getPage() != null ? salesRequest.getPage() : 0, // Page number is
                                                                                                       // zero-based
                        salesRequest.getSize() != null ? salesRequest.getSize() : 20);

                // Prepare response data
                reportData = new ArrayList<>();
                totalQuantity = 0;

                // Fetch all inventory items based on tenant name and date range
                inventory = inventoryRepository.findAll(spec, pageable);

                for (Inventory item : inventory) {
                    Long productId = Long.valueOf(item.getProduct_id());
                    String productName = productRepository.findProductNameById(productId, tenantName); // Fetch product
                                                                                                       // name
                    Long categoryId = productRepository.findCategoryIdByProductId(productId, tenantName); // Fetch
                                                                                                          // category ID
                    Long brandId = productRepository.findBrandIdByProductId(productId, tenantName); // Fetch brand ID
                    String categoryName = categoryRepository.findCategoryNameById(categoryId, tenantName); // Fetch
                                                                                                           // category
                                                                                                           // name
                    String brandName = brandRepository.findBrandNameById(brandId, tenantName); // Fetch brand name

                    // Convert quantity from String to int
                    int quantity = item.getTotal_quantity();

                    // Create report entry
                    Map<String, Object> reportEntry = new LinkedHashMap<>();
                    reportEntry.put("id", item.getId());
                    reportEntry.put("product_id", productId);
                    reportEntry.put("product_name", productName);
                    reportEntry.put("category_id", categoryId);
                    reportEntry.put("category_name", categoryName);
                    reportEntry.put("brand_id", brandId);
                    reportEntry.put("brand_name", brandName);
                    reportEntry.put("quantity", quantity);
                    if (quantity <= 10) {
                        reportEntry.put("stock_level", "Critical");
                    } else if (quantity > 10 && quantity <= 50) {
                        reportEntry.put("stock_level", "Low");
                    } else {
                        reportEntry.put("stock_level", "Sufficient");
                    }
                    reportEntry.put("date", String.valueOf(item.getCreated_at()));

                    reportData.add(reportEntry);

                    // Update totals
                    totalQuantity += quantity;
                }

                // Prepare column details
                column = new LinkedHashMap<>();
                column.put("id", "ID");
                column.put("product_id", "PRODUCT ID");
                column.put("product_name", "PRODUCT NAME");
                column.put("category_id", "CATEGORY ID");
                column.put("category_name", "CATEGORY NAME");
                column.put("brand_id", "BRAND ID");
                column.put("brand_name", "BRAND NAME");
                column.put("quantity", "QUANTITY");
                column.put("stock_level", "STOCK LEVEL");
                column.put("date", "DATE");

                // Prepare pagination details
                pagination = new LinkedHashMap<>();
                pagination.put("currentPage", inventory.getNumber() + 1); // Page number is 0-based
                pagination.put("totalPages", inventory.getTotalPages());
                pagination.put("pageSize", pageable.getPageSize());
                pagination.put("totalRecords", inventory.getTotalElements()); // Total records from the Page object

                // Prepare summary details
                summary = new LinkedHashMap<>();
                summary.put("totalQuantity", totalQuantity);
                summary.put("lowStockAlerts", calculateLowStockAlerts(inventory.getContent())); // Replace with your
                                                                                                // logic for low stock
                                                                                                // alerts

                // Prepare inventory response data
                inventoryResponseData = new LinkedHashMap<>();
                inventoryResponseData.put("module", "inventory");
                inventoryResponseData.put("reportType", reportType);
                inventoryResponseData.put("startDate", String.valueOf(fromDate));
                inventoryResponseData.put("endDate", String.valueOf(toDate));
                inventoryResponseData.put("reportData", reportData);
                inventoryResponseData.put("column", column);
                inventoryResponseData.put("pagination", pagination);
                inventoryResponseData.put("summary", summary);

                // Create and return the structured ApiResponseStructure
                return new ApiResponseStructure<>("Success", 200, "Data retrieved.", inventoryResponseData);
            case "inventoryValuation":
                // Add dynamic conditions
                if (salesRequest.getConditions() != null) {
                    for (SalesRequest.Condition condition : salesRequest.getConditions()) {
                        switch (condition.getOperator()) {
                            case "equals":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder
                                        .equal(root.get(condition.getField()), condition.getValue()));
                                break;
                            case "greaterThan":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder.greaterThan(
                                        root.get(condition.getField()), (Comparable) condition.getValue()));
                                break;
                            case "lessThan":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder
                                        .lessThan(root.get(condition.getField()), (Comparable) condition.getValue()));
                                break;
                            case "greaterThanOrEquals":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder.greaterThanOrEqualTo(
                                        root.get(condition.getField()), (Comparable) condition.getValue()));
                                break;
                            case "lessThanOrEquals":
                                spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder.lessThanOrEqualTo(
                                        root.get(condition.getField()), (Comparable) condition.getValue()));
                                break;
                            default:
                                createLogger.createLogger("error", path, "POST", "", "");
                                throw new IllegalArgumentException(
                                        "Operator " + condition.getOperator() + " is not supported.");
                        }
                    }
                }

                // Fetch the data with pagination for inventory
                pageable = PageRequest.of(salesRequest.getPage() != null ? salesRequest.getPage() : 0, // Page number is
                                                                                                       // zero-based
                        salesRequest.getSize() != null ? salesRequest.getSize() : 20);

                // Prepare response data
                reportData = new ArrayList<>();
                totalQuantity = 0;
                Double totalStockValue = 0.00; // Variable to hold total stock value

                // Fetch all inventory items based on tenant name and date range
                inventory = inventoryRepository.findAll(spec, pageable);

                for (Inventory item : inventory) {
                    Long productId = Long.valueOf(item.getProduct_id());
                    String productName = productRepository.findProductNameById(productId, tenantName); // Fetch product
                                                                                                       // name
                    Long categoryId = productRepository.findCategoryIdByProductId(productId, tenantName); // Fetch
                                                                                                          // category ID
                    Long brandId = productRepository.findBrandIdByProductId(productId, tenantName); // Fetch brand ID
                    String categoryName = categoryRepository.findCategoryNameById(categoryId, tenantName); // Fetch
                                                                                                           // category
                                                                                                           // name
                    String brandName = brandRepository.findBrandNameById(brandId, tenantName); // Fetch brand name

                    Double unitPrice = grnItemRepository
                            .findUnitPriceByProductAndTenant(item.getProduct_id(), tenantName, fromDateTime,
                                    toDateTime);

                    if (unitPrice == null) {
                        unitPrice = 0.0; // or continue; depending on business rule
                    }
                    int quantity = item.getTotal_quantity();

                    Double stockValue = unitPrice * quantity;

                    // Create report entry
                    Map<String, Object> reportEntry = new LinkedHashMap<>();
                    reportEntry.put("id", item.getId());
                    reportEntry.put("product_id", productId);
                    reportEntry.put("product_name", productName);
                    reportEntry.put("category_id", categoryId);
                    reportEntry.put("category_name", categoryName);
                    reportEntry.put("brand_id", brandId);
                    reportEntry.put("brand_name", brandName);
                    reportEntry.put("quantity", quantity);
                    reportEntry.put("stock_value", stockValue);
                    reportEntry.put("date", String.valueOf(item.getCreated_at()));
                    reportData.add(reportEntry);

                    // Update totals
                    totalQuantity += quantity;
                    totalStockValue = totalStockValue + (stockValue); // Update total stock value
                }

                // Prepare column details
                column = new LinkedHashMap<>();
                column.put("id", "ID");
                column.put("product_id", "PRODUCT ID");
                column.put("product_name", "PRODUCT NAME");
                column.put("category_id", "CATEGORY ID");
                column.put("category_name", "CATEGORY NAME");
                column.put("brand_id", "BRAND ID");
                column.put("brand_name", "BRAND NAME");
                column.put("quantity", "QUANTITY");
                column.put("stock_value", "STOCK VALUE");
                column.put("date", "DATE");

                // Prepare pagination details
                pagination = new LinkedHashMap<>();
                pagination.put("currentPage", inventory.getNumber() + 1); // Page number is 0-based
                pagination.put("totalPages", inventory.getTotalPages());
                pagination.put("pageSize", pageable.getPageSize());
                pagination.put("totalRecords", inventory.getTotalElements()); // Total records from the Page object

                // Prepare summary details
                summary = new LinkedHashMap<>();
                summary.put("totalQuantity", totalQuantity);
                summary.put("totalStockValue", MoneyUtils.truncateToTwoDecimals(totalStockValue)); // Add total stock
                                                                                                   // value to summary
                summary.put("lowStockAlerts", calculateLowStockAlerts(inventory.getContent())); // Replace with your
                                                                                                // logic for low stock
                                                                                                // alerts

                // Prepare inventory response data
                inventoryResponseData = new LinkedHashMap<>();
                inventoryResponseData.put("module", "inventory");
                inventoryResponseData.put("reportType", reportType);
                inventoryResponseData.put("startDate", String.valueOf(fromDate));
                inventoryResponseData.put("endDate", String.valueOf(toDate));
                inventoryResponseData.put("reportData", reportData);
                inventoryResponseData.put("column", column);
                inventoryResponseData.put("pagination", pagination);
                inventoryResponseData.put("summary", summary);

                // Create and return the structured ApiResponseStructure
                return new ApiResponseStructure<>("Success", 200, "Data retrieved.", inventoryResponseData);

            // case "productExpiration":
            // // Add dynamic conditions
            // if (salesRequest.getConditions() != null) {
            // for (SalesRequest.Condition condition : salesRequest.getConditions()) {
            // switch (condition.getOperator()) {
            // case "equals":
            // spec = spec.and((root, query, criteriaBuilder) ->
            // criteriaBuilder.equal(root.get(condition.getField()), condition.getValue()));
            // break;
            // case "greaterThan":
            // spec = spec.and((root, query, criteriaBuilder) ->
            // criteriaBuilder.greaterThan(root.get(condition.getField()), (Comparable)
            // condition.getValue()));
            // break;
            // case "lessThan":
            // spec = spec.and((root, query, criteriaBuilder) ->
            // criteriaBuilder.lessThan(root.get(condition.getField()), (Comparable)
            // condition.getValue()));
            // break;
            // case "greaterThanOrEquals":
            // spec = spec.and((root, query, criteriaBuilder) ->
            // criteriaBuilder.greaterThanOrEqualTo(root.get(condition.getField()),
            // (Comparable) condition.getValue()));
            // break;
            // case "lessThanOrEquals":
            // spec = spec.and((root, query, criteriaBuilder) ->
            // criteriaBuilder.lessThanOrEqualTo(root.get(condition.getField()),
            // (Comparable) condition.getValue()));
            // break;
            // default:
            // throw new IllegalArgumentException("Operator " + condition.getOperator() + "
            // is not supported.");
            // }
            // }
            // }
            //
            // // Fetch the data with pagination for inventory
            // pageable = PageRequest.of(salesRequest.getPage() != null ?
            // salesRequest.getPage() : 0, // Page number is zero-based
            // salesRequest.getSize() != null ? salesRequest.getSize() : 20);
            //
            // // Prepare response data
            // reportData = new ArrayList<>();
            // totalQuantity = 0;
            //
            // // Fetch all inventory items based on tenant name and date range
            // inventory = inventoryRepository.findAll(spec, pageable);
            //
            // for (Inventory item : inventory) {
            // Long productId = Long.valueOf(item.getProduct_id());
            // String productName = productRepository.findProductNameById(productId); //
            // Fetch product name
            // Long categoryId = productRepository.findCategoryIdByProductId(productId); //
            // Fetch category ID
            // Long brandId = productRepository.findBrandIdByProductId(productId); // Fetch
            // brand ID
            // String categoryName = categoryRepository.findCategoryNameById(categoryId); //
            // Fetch category name
            // String brandName = brandRepository.findBrandNameById(brandId); // Fetch brand
            // name
            //
            // // Convert quantity from String to int
            // int quantity = Integer.parseInt(item.getQuantity());
            //
            // // Create report entry
            // Map<String, Object> reportEntry = new LinkedHashMap<>();
            // reportEntry.put("id", item.getId());
            // reportEntry.put("product_id", productId);
            // reportEntry.put("product_name", productName);
            // reportEntry.put("category_id", categoryId);
            // reportEntry.put("category_name", categoryName);
            // reportEntry.put("brand_id", brandId);
            // reportEntry.put("brand_name", brandName);
            // reportEntry.put("quantity", quantity);
            // if (quantity <= 10) {
            // reportEntry.put("stock_level", "Critical");
            // } else if (quantity > 10 && quantity <= 50) {
            // reportEntry.put("stock_level", "Low");
            // } else {
            // reportEntry.put("stock_level", "Sufficient");
            // }
            //
            // reportData.add(reportEntry);
            //
            // // Update totals
            // totalQuantity += quantity;
            // }
            //
            // // Prepare column details
            // column = new LinkedHashMap<>();
            // column.put("id", "ID");
            // column.put("product_id", "PRODUCT ID");
            // column.put("product_name", "PRODUCT NAME");
            // column.put("category_id", "CATEGORY ID");
            // column.put("category_name", "CATEGORY NAME");
            // column.put("brand_id", "BRAND ID");
            // column.put("brand_name", "BRAND NAME");
            // column.put("quantity", "QUANTITY");
            // column.put("stock_level", "STOCK LEVEL");
            //
            // // Prepare pagination details
            // pagination = new LinkedHashMap<>();
            // pagination.put("currentPage", inventory.getNumber() + 1); // Page number is
            // 0-based
            // pagination.put("totalPages", inventory.getTotalPages());
            // pagination.put("pageSize", pageable.getPageSize());
            // pagination.put("totalRecords", inventory.getTotalElements()); // Total
            // records from the Page object
            //
            // // Prepare summary details
            // summary = new LinkedHashMap<>();
            // summary.put("totalQuantity", totalQuantity);
            // summary.put("lowStockAlerts",
            // calculateLowStockAlerts(inventory.getContent())); // Replace with your logic
            // for low stock alerts
            //
            // // Prepare inventory response data
            // inventoryResponseData = new LinkedHashMap<>();
            // inventoryResponseData.put("module", "inventory");
            // inventoryResponseData.put("reportType", reportType);
            // inventoryResponseData.put("startDate", fromDate);
            // inventoryResponseData.put("endDate", toDate);
            // inventoryResponseData.put("reportData", reportData);
            // inventoryResponseData.put("column", column);
            // inventoryResponseData.put("pagination", pagination);
            // inventoryResponseData.put("summary", summary);
            //
            // // Create and return the structured ApiResponseStructure
            // return new ApiResponseStructure<>("Success", 200, "Data retrieved.",
            // inventoryResponseData);

            default:
                createLogger.createLogger("error", path, "POST", "", "");
                return new ApiResponseStructure<>("Error", 400, "Invalid report type provided.", new HashMap<>());
        }
    }

    // Helper method to calculate low stock alerts
    private int calculateLowStockAlerts(List<Inventory> inventoryItems) {
        int lowStockCount = 0;
        for (Inventory item : inventoryItems) {
            int quantity = item.getTotal_quantity();
            if (quantity <= 10) { // Assuming a low stock threshold of 10
                lowStockCount++;
            }
        }
        return lowStockCount;
    }

}