<?php
/**
 * AJAX HTML for filtered product grids (shortcodes / pages without a native WooCommerce loop).
 */

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

add_action('wp_ajax_askagento_get_filtered_products', 'askagento_ajax_get_filtered_products');
add_action('wp_ajax_nopriv_askagento_get_filtered_products', 'askagento_ajax_get_filtered_products');

/**
 * Constrain attribute-filtered IDs by a text-search candidate list.
 *
 * @param int[]|null $filtered   null = no attribute filter (all products); array = matched IDs.
 * @param int[]|null $search_ids null = no text constraint; array = relevance-ordered IDs.
 * @return int[]|null null = all products; array = final IDs (ordered by search relevance
 *                    when a text constraint is present, possibly empty).
 */
function askagento_apply_search_constraint($filtered, $search_ids) {
    if ($search_ids === null) {
        return $filtered;
    }

    $search_ids = array_values(array_map('intval', $search_ids));

    if ($filtered === null) {
        return $search_ids;
    }

    $allow = array_flip(array_map('intval', $filtered));
    $out = [];
    foreach ($search_ids as $id) {
        if (isset($allow[$id])) {
            $out[] = $id;
        }
    }

    return $out;
}

/**
 * Render inner HTML for the product grid (ul.products or empty-state paragraph).
 *
 * @param int                 $filter_id  Filter post ID.
 * @param array<string,mixed> $current    Keys like _askagento_t_*, _askagento_m_*, _askagento_n_* (sanitized).
 * @param int[]|null          $search_ids Optional text-search constraint (connected [product_filter_search]).
 * @return string
 */
function askagento_render_filtered_products_inner_html($filter_id, array $current, $search_ids = null) {
    $filter_id = (int) $filter_id;
    if ($filter_id <= 0 || !function_exists('wc_get_template_part')) {
        return '';
    }

    $per_page = 12;
    if (function_exists('wc_get_default_products_per_row')) {
        $cols = max(1, (int) wc_get_default_products_per_row());
        $rows = 3;
        if (function_exists('wc_get_default_product_rows_per_page')) {
            $rows = max(1, (int) wc_get_default_product_rows_per_page());
        }
        $per_page = $cols * $rows;
    }
    $per_page = (int) apply_filters('askagento_filtered_products_per_page', $per_page, $filter_id);
    if ($per_page < 1) {
        $per_page = 12;
    }
    if ($per_page > 100) {
        $per_page = 100;
    }

    $ids = askagento_get_filtered_ids($filter_id, $current);
    $ids = askagento_apply_search_constraint($ids, $search_ids);

    if ($ids !== null && empty($ids)) {
        return '<p class="askagento-filter-no-results">' . esc_html__('No products match your filters.', 'askagento') . '</p>';
    }

    $args = [
        'post_type'           => 'product',
        'post_status'         => 'publish',
        'posts_per_page'      => $per_page,
        'ignore_sticky_posts' => true,
        'no_found_rows'       => false,
    ];

    if ($ids !== null) {
        $args['post__in'] = array_values(array_map('intval', $ids));
        $args['orderby'] = 'post__in';
    }

    $columns = 4;
    if (function_exists('wc_get_default_products_per_row')) {
        $columns = max(1, (int) wc_get_default_products_per_row());
    }
    $columns = (int) apply_filters('askagento_filtered_products_columns', $columns, $filter_id);

    $q = new WP_Query($args);

    ob_start();
    if ($q->have_posts()) {
        echo '<ul class="products columns-' . esc_attr((string) $columns) . '">';
        while ($q->have_posts()) {
            $q->the_post();
            wc_get_template_part('content', 'product');
        }
        echo '</ul>';
    } else {
        echo '<p class="askagento-filter-no-results">' . esc_html__('No products found.', 'askagento') . '</p>';
    }
    wp_reset_postdata();

    return ob_get_clean();
}

/**
 * JSON: HTML fragment for filtered products + total line HTML.
 */
function askagento_ajax_get_filtered_products() {
    check_ajax_referer('askagento_filter', 'nonce');

    $filter_id = isset($_POST['filter_id']) ? absint(wp_unslash($_POST['filter_id'])) : 0;
    if ($filter_id <= 0 || get_post_type($filter_id) !== ASKAGENTO_POST_TYPE) {
        wp_send_json_error(['message' => 'Invalid filter']);
    }

    if (!function_exists('wc_get_template_part')) {
        wp_send_json_error(['message' => 'WooCommerce is required']);
    }

    $sanitized = askagento_sanitize_filter_current_array(isset($_POST['current']) ? (array) map_deep( wp_unslash( $_POST['current'] ), 'sanitize_text_field' ) : []);

    // Connected [product_filter_search]: narrow the grid to the text query, ordered by relevance.
    $query = isset($_POST['q']) ? sanitize_text_field(wp_unslash($_POST['q'])) : '';
    $search_ids = ($query !== '' && function_exists('askagento_ai_text_search_candidate_ids'))
        ? askagento_ai_text_search_candidate_ids($query)
        : null;

    $html = askagento_render_filtered_products_inner_html($filter_id, $sanitized, $search_ids);

    if ($search_ids === null) {
        $total = askagento_get_total_count($filter_id, $sanitized);
    } else {
        $combined = askagento_apply_search_constraint(
            askagento_get_filtered_ids($filter_id, $sanitized),
            $search_ids
        );
        $total = is_array($combined) ? count($combined) : 0;
    }
    $total_html = sprintf(
        /* translators: %d: product count */
        __('Found: <strong>%d</strong> products', 'askagento'),
        $total
    );

    wp_send_json_success(
        [
            'html'       => $html,
            'total_html' => $total_html,
        ]
    );
}
