<?php
/**
 * Search result processing
 *
 * Handles fetching, merging, and processing search results from PA-API.
 * This module encapsulates the common pattern of fetching page 1 + page 2
 * and merging them for better filter options and initial display.
 */

if (!defined('ABSPATH')) {
    exit;
}

require_once PSFA_PLUGIN_DIR . 'src/core/search/functions.php';

/**
 * Fetch and merge search results for pages 1 and 2.
 *
 * This is a common pattern used throughout the plugin to:
 * - Get initial results (page 1)
 * - Get additional results (page 2) for better filter options
 * - Merge them together for initial display
 *
 * @param string $query Search query/keyword.
 * @param string $category Category filter.
 * @param string $sort Sort option.
 * @param string $brand Brand filter.
 * @param string $condition Condition filter.
 * @param string $merchant Merchant filter.
 * @param string $has_deal Premium: Has Deal filter.
 * @param int    $min_rating Premium: Minimum customer rating (1-5).
 * @param int    $min_saving_percent Premium: Minimum discount percentage.
 * @param string $availability Availability filter ('Available', 'IncludeOutOfStock', 'OutOfStockOnly').
 * @return array {
 *   @type array|null page1_results Raw API response for page 1
 *   @type array|null page2_results Raw API response for page 2
 *   @type array merged_items Combined items from both pages
 *   @type array|null search_refinements SearchRefinements from page 1
 *   @type string error_message Error message if any
 * }
 */
function psfa_fetch_and_merge_pages($query, $category, $sort, $brand, $condition, $merchant, $has_deal = '', $min_rating = 0, $min_saving_percent = 0, $availability = '', $price_min = 0, $price_max = 0) {
    $result = array(
        'page1_results' => null,
        'page2_results' => null,
        'merged_items' => array(),
        'search_refinements' => null,
        'error_message' => '',
    );

    // Fetch page 1
    $page1_results = psfa_amazon_search_products($query, $category, $price_min, $price_max, 1, $sort, $brand, $condition, $merchant, $has_deal, $min_rating, $min_saving_percent, $availability);
    
    if (isset($page1_results['error'])) {
        $result['error_message'] = $page1_results['error'];
        if (isset($page1_results['details'])) {
            $result['error_message'] .= ' - ' . json_encode($page1_results['details']);
        }
        return $result;
    }

    if (!isset($page1_results['SearchResult']['Items'])) {
        return $result;
    }

    $result['page1_results'] = $page1_results;
    $result['merged_items'] = $page1_results['SearchResult']['Items'];
    $result['search_refinements'] = $page1_results['SearchResult']['SearchRefinements'] ?? null;

    // Fetch page 2 with same parameters
    $page2_results = psfa_amazon_search_products($query, $category, $price_min, $price_max, 2, $sort, $brand, $condition, $merchant, $has_deal, $min_rating, $min_saving_percent, $availability);
    
    if (isset($page2_results['SearchResult']['Items']) && !empty($page2_results['SearchResult']['Items'])) {
        $result['page2_results'] = $page2_results;
        $result['merged_items'] = array_merge($result['merged_items'], $page2_results['SearchResult']['Items']);
    }

    return $result;
}

/**
 * Apply client-side filtering and sorting to items.
 *
 * This handles:
 * - Price filtering (client-side, as PA-API doesn't support MinPrice/MaxPrice)
 * - Condition filtering (PA-API Condition is a hint, not strict)
 * - Merchant filtering (PA-API Merchant is a hint, not strict)
 * - Availability filtering (for OutOfStockOnly, PA-API doesn't support this directly)
 * - Prime filtering (PA-API DeliveryFlags is a hint, not strict)
 * - Savings/discount filtering (to enforce MinSavingPercent even when API returns products without savings data)
 * - Client-side sorting (when server-side sorting isn't available)
 *
 * @param array $items Items to process.
 * @param float $min_price Minimum price filter (0 to disable).
 * @param float $max_price Maximum price filter (0 to disable).
 * @param string $sort Sort option.
 * @param string $brand Brand filter (used to determine if client-side sort needed).
 * @param int $min_saving_percent Minimum discount percentage (0 to disable).
 * @param string $has_deal Has deal filter (empty to disable, '1' to filter for items with deals).
 * @param string $condition Condition filter (empty to disable).
 * @param string $merchant Merchant filter (empty to disable).
 * @param string $availability Availability filter (empty to disable, 'OutOfStockOnly' for client-side filtering).
 * @return array Processed items.
 */
function psfa_apply_client_side_processing($items, $min_price, $max_price, $sort, $brand, $min_saving_percent = 0, $has_deal = '', $condition = '', $merchant = '', $availability = '') {
    if (empty($items) || !is_array($items)) {
        return $items;
    }

    // Apply price filtering client-side
    // Note: Creators API claims to support minPrice/maxPrice but doesn't honor them reliably
    // Always apply client-side filtering as a safety net
    if ($min_price > 0 || $max_price > 0) {
        $items = psfa_filter_products_by_price($items, $min_price, $max_price);
    }

    // Apply Condition filtering client-side
    // PA-API Condition is a hint, not a strict filter - enforce it here
    if (!empty($condition)) {
        $items = psfa_filter_products_by_condition($items, $condition);
    }

    // Apply Merchant filtering client-side
    // PA-API Merchant is a hint, not a strict filter - enforce it here
    if (!empty($merchant)) {
        $items = psfa_filter_products_by_merchant($items, $merchant);
    }

    // Apply Availability filtering client-side for "Out of Stock Only"
    // PA-API only supports Available or IncludeOutOfStock, not OutOfStockOnly
    if ($availability === 'OutOfStockOnly') {
        $items = psfa_filter_products_by_availability($items, 'OutOfStockOnly');
    }

    

    // Apply client-side sorting if needed
    if (psfa_needs_client_sort($brand, $sort, $min_price, $max_price, $has_deal, $min_saving_percent)) {
        $items = psfa_sort_items($items, $sort);
    }

    return $items;
}

/**
 * Filter products by condition.
 *
 * PA-API Condition filter is a hint, not a strict filter - it may still return
 * items with different conditions. This function enforces strict filtering.
 *
 * @param array $items Items to filter.
 * @param string $condition Condition filter value ('New', 'Used', 'Refurbished', 'Collectible').
 * @return array Filtered items.
 */
function psfa_filter_products_by_condition($items, $condition) {
    if (empty($condition)) {
        return $items;
    }

    $valid_conditions = array('New', 'Used', 'Refurbished', 'Collectible');
    if (!in_array($condition, $valid_conditions, true)) {
        return $items;
    }

    return array_values(array_filter($items, function($item) use ($condition) {
        $item_condition = psfa_get_item_condition($item);
        
        // If no condition data from PA-API, trust that PA-API already filtered correctly
        // PA-API doesn't always return Condition data even when requested
        if (empty($item_condition)) {
            return true;
        }
        
        return strcasecmp($item_condition, $condition) === 0;
    }));
}

/**
 * Filter products by availability/stock status.
 *
 * PA-API only supports 'Available' (default) or 'IncludeOutOfStock'.
 * This function enables "Out of Stock Only" filtering client-side.
 *
 * @param array $items Items to filter.
 * @param string $availability Availability filter value ('OutOfStockOnly').
 * @return array Filtered items.
 */
function psfa_filter_products_by_availability($items, $availability) {
    if (empty($availability)) {
        return $items;
    }

    return array_values(array_filter($items, function($item) use ($availability) {
        $avail_type = psfa_get_item_availability_type($item);
        $avail_message = psfa_get_item_availability_message($item);
        
        // Check if item is out of stock
        // Type "Now" means in stock, other types or "out of stock" message means not available
        $is_out_of_stock = (
            $avail_type !== 'Now' ||
            stripos($avail_message, 'out of stock') !== false ||
            stripos($avail_message, 'unavailable') !== false
        );
        
        if ($availability === 'OutOfStockOnly') {
            return $is_out_of_stock;
        }
        
        return true;
    }));
}

/**
 * Filter products by merchant.
 *
 * PA-API Merchant filter is a hint, not a strict filter - it may still return
 * items from different merchants. This function enforces strict filtering.
 *
 * @param array $items Items to filter.
 * @param string $merchant Merchant filter value ('Amazon').
 * @return array Filtered items.
 */
function psfa_filter_products_by_merchant($items, $merchant) {
    if (empty($merchant) || $merchant === 'All') {
        return $items;
    }

    return array_values(array_filter($items, function($item) use ($merchant) {
        $item_merchant = psfa_get_item_merchant($item);
        
        // If no merchant data from PA-API, trust that PA-API already filtered correctly
        // PA-API doesn't always return MerchantInfo data even when requested
        if (empty($item_merchant)) {
            return true;
        }
        
        // Match "Amazon" or "Amazon.com"
        if ($merchant === 'Amazon') {
            return strcasecmp($item_merchant, 'Amazon') === 0 || 
                   strcasecmp($item_merchant, 'Amazon.com') === 0;
        }
        
        return strcasecmp($item_merchant, $merchant) === 0;
    }));
}



