<?php

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

trait Niwa_AI_Tools_Product_Search {

    public function lookup_woo_products( $query, $statuses = array(), $limit = 5, $options = array() ) {
        $reference = $this->normalize_product_lookup_reference( $this->parse_product_lookup_reference( $query ), $limit, $options );
        $limit     = intval( $reference['lookup_limit'] );
        if (
            ! empty( $reference['category_id'] )
            || '' !== $reference['category_slug']
        ) {
            return $this->find_products_by_category_reference( $reference, $statuses, $limit );
        }
        $exact_products = $this->find_exact_products_by_query( $query, $statuses, $limit );
        $exact_products = $this->slice_filtered_product_targets( $exact_products, $reference );
        if ( ! empty( $exact_products ) ) {
            return $exact_products;
        }

        if ( ! empty( $reference['exact_only'] ) ) {
            return array();
        }

        $identity_products = $this->find_direct_product_identity_matches_by_query(
            isset( $reference['query'] ) ? $reference['query'] : $query,
            $statuses,
            $limit
        );
        $identity_products = $this->slice_filtered_product_targets( $identity_products, $reference );
        if ( ! empty( $identity_products ) ) {
            return $identity_products;
        }

        return $this->find_products_by_query( isset( $reference['query'] ) ? $reference['query'] : $query, $statuses, $limit, $reference );
    }

    public function lookup_woo_variations( $product_query, $variation_attributes = array(), $statuses = array(), $limit = 10 ) {
        $limit = max( 1, min( 20, intval( $limit ) ) );
        $variation_lookup = $this->extract_exact_variation_lookup_hints( $product_query, (array) $variation_attributes );
        $normalized_statuses = $this->normalize_variation_statuses( $statuses );

        if ( ! empty( $variation_lookup['variation_id'] ) ) {
            $variation_id = intval( $variation_lookup['variation_id'] );
            $variation    = wc_get_product( $variation_id );
            if ( $variation && $variation->is_type( 'variation' ) ) {
                $parent = wc_get_product( $variation->get_parent_id() );
                if ( $parent && $parent->is_type( 'variable' ) ) {
                    $parent_id = intval( $parent->get_id() );
                    $parent_post = get_post( $parent_id );
                    if ( ! $parent_post ) {
                        return array();
                    }
                    if ( 0 !== intval( $variation_lookup['parent_id'] ) && $parent_id !== intval( $variation_lookup['parent_id'] ) ) {
                        return array();
                    }

                    $target = $this->build_variation_bulk_target( $variation, $parent_post );
                    $target['exact_match'] = true;
                    $target['price_display'] = $this->format_price_display_value( $target['price'] );
                    $target['regular_price_display'] = $this->format_price_display_value( $target['regular_price'] );
                    $target['sale_price_display'] = $this->format_price_display_value( $target['sale_price'] );

                    if ( ! empty( $variation_lookup['filtered_meta'] ) ) {
                        $normalized = $this->normalize_variation_attributes_for_product( $parent, $variation_lookup['filtered_meta'] );
                        if ( empty( $normalized['success'] ) ) {
                            return array();
                        }

                        if ( ! $this->variation_target_matches_filter( $target['attributes'], $normalized['meta'] ) ) {
                            return array();
                        }
                    }

                    return array( $target );
                }
            }

            if ( ! empty( $variation_lookup['exact_only'] ) ) {
                return array();
            }
        }

        $resolved = $this->resolve_variable_product_from_args(
            array(
                'product_id'    => $variation_lookup['product_id'],
                'parent_id'     => $variation_lookup['parent_id'],
                'product_query' => $variation_lookup['product_query'],
                'sku'           => $variation_lookup['sku'],
                'exact_only'    => $variation_lookup['exact_only'],
            )
        );
        if ( empty( $resolved['success'] ) ) {
            return array();
        }

        $normalized = array();
        if ( ! empty( $variation_lookup['filtered_meta'] ) ) {
            $normalized_result = $this->normalize_variation_attributes_for_product( $resolved['product'], (array) $variation_lookup['filtered_meta'] );
            if ( empty( $normalized_result['success'] ) ) {
                return array();
            }
            $normalized = $normalized_result['meta'];
        }

        $variations = $this->get_variation_targets_for_product( $resolved['product'], $normalized, $normalized_statuses, $limit );
        foreach ( $variations as &$variation ) {
            $variation['price_display'] = $this->format_price_display_value( isset( $variation['price'] ) ? $variation['price'] : '' );
            $variation['regular_price_display'] = $this->format_price_display_value( isset( $variation['regular_price'] ) ? $variation['regular_price'] : '' );
            $variation['sale_price_display'] = $this->format_price_display_value( isset( $variation['sale_price'] ) ? $variation['sale_price'] : '' );
            $variation['exact_match'] = ! empty( $variation_lookup['exact_only'] );
        }
        unset( $variation );

        return $variations;
    }

    private function find_exact_products_by_query( $query, $statuses = array(), $limit = 5 ) {
        $reference = $this->parse_product_lookup_reference( $query );
        if ( empty( $reference['exact_only'] ) ) {
            return array();
        }

        $resolved = array();
        if ( ! empty( $reference['product_id'] ) ) {
            $post = get_post( intval( $reference['product_id'] ) );
            $product = wc_get_product( intval( $reference['product_id'] ) );
            if ( $post && $product ) {
                if ( 'product' === (string) $post->post_type ) {
                    $target = $this->hydrate_resolved_product_target(
                        array(
                            'post_id' => intval( $post->ID ),
                            'score'   => 200,
                            'source'  => 'exact_id',
                        )
                    );
                    if ( ! empty( $target ) ) {
                        $target['exact_match'] = true;
                        $target['match_confidence'] = 'high';
                        $resolved[] = $target;
                    }
                } elseif ( 'product_variation' === (string) $post->post_type ) {
                    $parent_product = wc_get_product( intval( $product->get_parent_id() ) );
                    $parent_post    = $parent_product ? get_post( intval( $parent_product->get_id() ) ) : null;
                    if ( $parent_product && $parent_product->is_type( 'variable' ) && $parent_post ) {
                        $target = $this->build_variation_bulk_target( $product, $parent_post );
                        $target['exact_match'] = true;
                        $target['match_confidence'] = 'high';
                        $target['price_display'] = $this->format_price_display_value( $target['price'] );
                        $target['regular_price_display'] = $this->format_price_display_value( $target['regular_price'] );
                        $target['sale_price_display'] = $this->format_price_display_value( $target['sale_price'] );
                        $resolved[] = $target;
                    }
                }
            }
        } elseif ( '' !== $reference['sku'] ) {
            $sku_id = function_exists( 'wc_get_product_id_by_sku' ) ? wc_get_product_id_by_sku( $reference['sku'] ) : 0;
            if ( $sku_id > 0 ) {
                $sku_post = get_post( intval( $sku_id ) );
                $sku_product = wc_get_product( intval( $sku_id ) );
                if ( $sku_post && $sku_product ) {
                    if ( 'product' === (string) $sku_post->post_type ) {
                        $target = $this->hydrate_resolved_product_target(
                            array(
                                'post_id' => intval( $sku_post->ID ),
                                'score'   => 200,
                                'source'  => 'exact_sku',
                            )
                        );
                        if ( ! empty( $target ) ) {
                            $target['exact_match'] = true;
                            $target['match_confidence'] = 'high';
                            $resolved[] = $target;
                        }
                    } elseif ( 'product_variation' === (string) $sku_post->post_type ) {
                        $parent_product = wc_get_product( intval( $sku_product->get_parent_id() ) );
                        $parent_post    = $parent_product ? get_post( intval( $parent_product->get_id() ) ) : null;
                        if ( $parent_product && $parent_product->is_type( 'variable' ) && $parent_post ) {
                            $target = $this->build_variation_bulk_target( $sku_product, $parent_post );
                            $target['exact_match'] = true;
                            $target['match_confidence'] = 'high';
                            $target['price_display'] = $this->format_price_display_value( $target['price'] );
                            $target['regular_price_display'] = $this->format_price_display_value( $target['regular_price'] );
                            $target['sale_price_display'] = $this->format_price_display_value( $target['sale_price'] );
                            $resolved[] = $target;
                        }
                    }
                }
            }
        } elseif ( '' !== $reference['exact_query'] ) {
            $resolved = $this->find_products_by_exact_title_or_slug( $reference['exact_query'], $statuses, $limit );
        }

        return array_values(
            array_filter(
                $resolved,
                function ( $target ) {
                    return is_array( $target ) && ! empty( $target['post_id'] );
                }
            )
        );
    }

    private function find_products_by_exact_title_or_slug( $query, $statuses = array(), $limit = 5 ) {
        if ( ! function_exists( 'wc_get_product' ) ) {
            return array();
        }

        $query    = trim( (string) $query );
        $limit    = max( 1, min( 20, intval( $limit ) ) );
        $statuses = $this->normalize_product_statuses( $statuses );
        if ( '' === $query ) {
            return array();
        }

        $found = array();
        $seen  = array();

        $add_post = function ( $post ) use ( &$found, &$seen, $statuses ) {
            if ( ! $post || empty( $post->ID ) || isset( $seen[ intval( $post->ID ) ] ) ) {
                return;
            }
            if ( 'product' !== (string) $post->post_type ) {
                return;
            }
            if ( ! in_array( (string) $post->post_status, $statuses, true ) ) {
                return;
            }

            $product = wc_get_product( intval( $post->ID ) );
            if ( ! $product ) {
                return;
            }

            $target          = $this->build_product_target( $post, $product );
            $target['score'] = 200;
            $target['exact_match'] = true;
            $target['match_confidence'] = 'high';
            $found[]         = $target;
            $seen[ $target['post_id'] ] = true;
        };

        $slug_posts = get_posts(
            array(
                'post_type'      => 'product',
                'post_status'    => $statuses,
                'posts_per_page' => 3,
                'name'           => sanitize_title( $query ),
            )
        );
        foreach ( (array) $slug_posts as $post ) {
            $add_post( $post );
        }

        if ( count( $found ) < $limit ) {
            global $wpdb;
            $status_placeholders = implode( ',', array_fill( 0, count( $statuses ), '%s' ) );
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            $title_ids = $wpdb->get_col( $wpdb->prepare(
                "SELECT ID FROM {$wpdb->posts}
                 WHERE post_type = 'product'
                 AND post_status IN ({$status_placeholders})
                 AND post_title = %s
                 LIMIT %d",
                array_merge( $statuses, array( $query, $limit ) )
            ) );
            if ( ! empty( $title_ids ) ) {
                foreach ( $title_ids as $tid ) {
                    $add_post( get_post( intval( $tid ) ) );
                }
            }
        }

        return array_slice( $found, 0, $limit );
    }

    private function parse_product_lookup_reference( $query ) {
        $raw = trim( (string) $query );
        $normalized = strtolower( $raw );
        $result = array(
            'raw'                   => $raw,
            'query'                 => $raw,
            'product_id'            => 0,
            'sku'                   => '',
            'category_id'           => 0,
            'category_slug'         => '',
            'exclude_category_id'   => 0,
            'exclude_category_slug' => '',
            'onsale_only'           => false,
            'offset'                => 0,
            'page'                  => 1,
            'lookup_limit'          => 5,
            'exact_only'            => false,
            'exact_query'           => '',
        );

        if ( '' === $raw ) {
            return $result;
        }

        if ( preg_match( '/^(?:exact|exact_only)\s*:\s*(.+)$/i', $raw, $matches ) ) {
            $result['exact_only']  = true;
            $result['exact_query'] = trim( (string) $matches[1] );
            $result['query']       = $result['exact_query'];
            return $result;
        }

        if ( preg_match( '/^(?:product_id|parent_id|id)\s*:\s*(\d+)$/i', $raw, $matches ) ) {
            $result['product_id']  = intval( $matches[1] );
            $result['exact_only']  = true;
            $result['exact_query'] = $result['raw'];
            return $result;
        }

        if ( ctype_digit( $raw ) ) {
            $result['product_id']  = intval( $raw );
            $result['exact_only']  = true;
            $result['exact_query'] = $result['raw'];
            return $result;
        }

        if ( preg_match( '/^sku\s*:\s*(.+)$/i', $raw, $matches ) ) {
            $result['sku']         = trim( (string) $matches[1] );
            $result['exact_only']  = true;
            $result['exact_query'] = $result['sku'];
            return $result;
        }

        if ( preg_match( '/^category_id\s*:\s*(\d+)$/i', $raw, $matches ) ) {
            $result['category_id'] = intval( $matches[1] );
            $result['query']       = '';
            return $result;
        }

        if ( preg_match( '/^category_slug\s*:\s*(.+)$/i', $raw, $matches ) ) {
            $result['category_slug'] = sanitize_title( trim( (string) $matches[1] ) );
            $result['query']         = '';
            return $result;
        }

        $result['query'] = $raw;
        return $result;
    }

    private function normalize_product_lookup_reference( $reference, $limit, $options = array() ) {
        $reference = is_array( $reference ) ? $reference : array();
        $options   = is_array( $options ) ? $options : array();
        $limit     = max( 1, min( 50, intval( $limit ) ) );
        $page      = isset( $options['page'] ) ? max( 1, intval( $options['page'] ) ) : max( 1, intval( isset( $reference['page'] ) ? $reference['page'] : 1 ) );
        $offset    = array_key_exists( 'offset', $options )
            ? max( 0, intval( $options['offset'] ) )
            : max( 0, intval( isset( $reference['offset'] ) ? $reference['offset'] : ( ( $page - 1 ) * $limit ) ) );

        $reference['onsale_only']           = ! empty( $options['onsale_only'] ) || ! empty( $reference['onsale_only'] );
        $reference['exclude_category_id']   = isset( $options['exclude_category_id'] ) ? max( 0, intval( $options['exclude_category_id'] ) ) : max( 0, intval( isset( $reference['exclude_category_id'] ) ? $reference['exclude_category_id'] : 0 ) );
        $reference['exclude_category_slug'] = isset( $options['exclude_category_slug'] ) ? sanitize_title( (string) $options['exclude_category_slug'] ) : sanitize_title( isset( $reference['exclude_category_slug'] ) ? (string) $reference['exclude_category_slug'] : '' );
        $reference['page']                  = $page;
        $reference['offset']                = $offset;
        $reference['lookup_limit']          = $limit;

        return $reference;
    }

    private function extract_exact_variation_lookup_hints( $product_query, $variation_attributes ) {
        $variation_attributes = is_array( $variation_attributes ) ? $variation_attributes : array();
        $hints = array(
            'product_query'  => trim( (string) $product_query ),
            'product_id'     => 0,
            'parent_id'      => 0,
            'variation_id'   => 0,
            'sku'            => '',
            'exact_only'     => false,
            'filtered_meta'  => array(),
        );

        foreach ( $variation_attributes as $raw_key => $raw_value ) {
            $key   = $this->normalize_variation_key( $raw_key );
            $value = trim( (string) $raw_value );
            if ( '' === $key ) {
                continue;
            }

            if ( in_array( $key, array( 'variationid', 'variation_id' ), true ) ) {
                $hints['variation_id'] = intval( $value );
                $hints['exact_only']    = true;
                continue;
            }
            if ( in_array( $key, array( 'parentid', 'parent_id', 'productid', 'product_id' ), true ) ) {
                $hints['product_id'] = intval( $value );
                $hints['parent_id']  = intval( $value );
                $hints['exact_only']  = true;
                continue;
            }
            if ( in_array( $key, array( 'sku', 'productsku' ), true ) ) {
                $hints['sku']       = $value;
                $hints['exact_only'] = true;
                continue;
            }
            if ( in_array( $key, array( 'exactonly', 'exact_only', 'exact' ), true ) ) {
                $hints['exact_only'] = filter_var( $value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
                if ( null === $hints['exact_only'] ) {
                    $hints['exact_only'] = true;
                }
                continue;
            }

            $hints['filtered_meta'][ $raw_key ] = $raw_value;
        }

        if ( '' !== $hints['product_query'] ) {
            $query_reference = $this->parse_product_lookup_reference( $hints['product_query'] );
            if ( ! empty( $query_reference['product_id'] ) ) {
                $hints['product_id'] = intval( $query_reference['product_id'] );
                $hints['parent_id']   = intval( $query_reference['product_id'] );
                $hints['exact_only']  = true;
            }
            if ( ! empty( $query_reference['sku'] ) ) {
                $hints['sku']        = (string) $query_reference['sku'];
                $hints['exact_only']  = true;
            }
            if ( ! empty( $query_reference['exact_only'] ) ) {
                $hints['exact_only'] = true;
                if ( '' !== $query_reference['exact_query'] ) {
                    $hints['product_query'] = (string) $query_reference['exact_query'];
                }
            }
        }

        return $hints;
    }

    private function variation_target_matches_filter( $target_attributes, $filter_meta ) {
        $target_attributes = is_array( $target_attributes ) ? $target_attributes : array();
        $filter_meta       = is_array( $filter_meta ) ? $filter_meta : array();

        foreach ( $filter_meta as $key => $value ) {
            if ( ! array_key_exists( $key, $target_attributes ) || (string) $target_attributes[ $key ] !== (string) $value ) {
                return false;
            }
        }

        return true;
    }

    private function format_price_display_value( $value ) {
        $value = trim( (string) $value );
        if ( '' === $value ) {
            return '';
        }

        $normalized = $this->normalize_decimal_price( $value );
        if ( null === $normalized ) {
            return $value;
        }

        if ( function_exists( 'wc_price' ) ) {
            $formatted = wp_strip_all_tags(
                html_entity_decode(
                    wc_price( (float) $normalized ),
                    ENT_QUOTES,
                    'UTF-8'
                )
            );
            $formatted = preg_replace( '/\s+/', ' ', trim( (string) $formatted ) );
            if ( '' !== $formatted ) {
                return $formatted;
            }
        }

        $decimals = function_exists( 'wc_get_price_decimals' ) ? max( 0, intval( wc_get_price_decimals() ) ) : 0;
        return number_format( (float) $normalized, $decimals, '.', '' );
    }

    private function find_products_by_category_reference( $reference, $statuses = array(), $limit = 5 ) {
        if ( ! function_exists( 'wc_get_product' ) ) {
            return array();
        }

        $statuses      = $this->normalize_product_statuses( $statuses );
        $limit         = max( 1, min( 50, intval( $limit ) ) );
        $offset        = max( 0, intval( isset( $reference['offset'] ) ? $reference['offset'] : 0 ) );
        $category_id   = isset( $reference['category_id'] ) ? intval( $reference['category_id'] ) : 0;
        $category_slug = isset( $reference['category_slug'] ) ? sanitize_title( (string) $reference['category_slug'] ) : '';
        $exclude_category_id   = isset( $reference['exclude_category_id'] ) ? intval( $reference['exclude_category_id'] ) : 0;
        $exclude_category_slug = isset( $reference['exclude_category_slug'] ) ? sanitize_title( (string) $reference['exclude_category_slug'] ) : '';
        $search_query  = isset( $reference['query'] ) ? trim( (string) $reference['query'] ) : '';

        if ( $category_id <= 0 && '' === $category_slug && $exclude_category_id <= 0 && '' === $exclude_category_slug && empty( $reference['onsale_only'] ) ) {
            return array();
        }

        $tax_query = array();
        if ( $category_id > 0 || '' !== $category_slug ) {
            $tax_query[] = array(
                'taxonomy' => 'product_cat',
                'field'    => $category_id > 0 ? 'term_id' : 'slug',
                'terms'    => array( $category_id > 0 ? $category_id : $category_slug ),
            );
        }
        if ( $exclude_category_id > 0 || '' !== $exclude_category_slug ) {
            $tax_query[] = array(
                'taxonomy' => 'product_cat',
                'field'    => $exclude_category_id > 0 ? 'term_id' : 'slug',
                'terms'    => array( $exclude_category_id > 0 ? $exclude_category_id : $exclude_category_slug ),
                'operator' => 'NOT IN',
            );
        }
        if ( count( $tax_query ) > 1 ) {
            $tax_query['relation'] = 'AND';
        }

        $scan_limit = min( 1000, max( 50, $limit + $offset + 20 ) );
        $posts = get_posts(
            array(
                'post_type'      => 'product',
                'post_status'    => $statuses,
                'posts_per_page' => $scan_limit,
                'orderby'        => 'date',
                'order'          => 'DESC',
                'tax_query'      => $tax_query,
            )
        );

        $products = array();
        foreach ( (array) $posts as $post ) {
            $product = wc_get_product( intval( $post->ID ) );
            if ( ! $product ) {
                continue;
            }

            $target          = $this->build_product_target( $post, $product );
            $target['score'] = '' !== $search_query
                ? $this->score_product_match( $search_query, $target, $statuses )
                : 100;

            if ( '' !== $search_query && intval( $target['score'] ) < 25 ) {
                continue;
            }

            $products[] = $target;
        }

        return $this->slice_filtered_product_targets( $products, $reference );
    }

    /**
     * Find a single best-matching product, with confidence metadata.
     *
     * Adds 'match_confidence' ('high', 'medium', 'low') and an optional
     * 'match_warning' string when the match quality is uncertain.  The AI
     * preview step surfaces the warning so the founder can confirm.
     */
    private function find_product_by_query( $query, $statuses = array() ) {
        $query = trim( (string) $query );
        if ( '' === $query ) {
            return array();
        }
        $resolved = $this->resolve_best_product_via_target_resolver( $query, $statuses );
        if ( ! empty( $resolved ) ) {
            return $resolved;
        }

        $products = $this->find_products_by_query( $query, $statuses, 3 );
        if ( empty( $products[0] ) ) {
            return array();
        }

        $best  = $products[0];
        $score = intval( isset( $best['score'] ) ? $best['score'] : 0 );

        // Determine confidence level.
        if ( $score >= 100 ) {
            $best['match_confidence'] = 'high';
        } elseif ( $score >= 50 ) {
            $best['match_confidence'] = 'medium';
        } else {
            $best['match_confidence'] = 'low';
            $best['match_warning']    = 'Nisam siguran da je ovo pravi proizvod (score: ' . $score . '). Potvrdi pre izmene.';
        }

        // Ambiguity check: if top two results are very close in score, warn.
        if ( ! empty( $products[1] ) ) {
            $runner_up_score = intval( isset( $products[1]['score'] ) ? $products[1]['score'] : 0 );
            if ( $runner_up_score > 0 && ( $score - $runner_up_score ) < 15 ) {
                $best['match_warning'] = sprintf(
                    'Dvosmislen rezultat — "%s" (score %d) je blizu "%s" (score %d). Potvrdi koji je pravi proizvod.',
                    isset( $best['post_title'] ) ? (string) $best['post_title'] : '?',
                    $score,
                    isset( $products[1]['post_title'] ) ? (string) $products[1]['post_title'] : '?',
                    $runner_up_score
                );
            }
        }

        return $best;
    }

    private function find_products_by_query( $query, $statuses = array(), $limit = 5, $reference = array() ) {
        if ( ! function_exists( 'wc_get_product' ) ) {
            return array();
        }

        $query    = trim( (string) $query );
        $limit    = max( 1, min( 50, intval( $limit ) ) );
        $statuses = $this->normalize_product_statuses( $statuses );
        $offset   = max( 0, intval( isset( $reference['offset'] ) ? $reference['offset'] : 0 ) );
        $scan_limit = min( 1000, max( 20, $limit + $offset + 20 ) );
        if ( '' === $query ) {
            return $this->list_catalog_products_by_statuses( $statuses, $scan_limit, $reference );
        }

        $resolved = $this->resolve_products_via_target_resolver( $query, $statuses, $scan_limit );
        if ( ! empty( $resolved ) ) {
            foreach ( $resolved as &$target ) {
                $target['score'] = $this->score_product_match( $query, $target, $statuses );
            }
            unset( $target );

            usort(
                $resolved,
                function ( $a, $b ) {
                    return intval( isset( $b['score'] ) ? $b['score'] : 0 ) <=> intval( isset( $a['score'] ) ? $a['score'] : 0 );
                }
            );

            return $this->slice_filtered_product_targets( $resolved, $reference );
        }

        $found = array();
        $seen  = array();

        $add_post = function ( $post ) use ( &$found, &$seen, $query, $statuses ) {
            if ( ! $post || empty( $post->ID ) || isset( $seen[ intval( $post->ID ) ] ) ) {
                return;
            }
            if ( 'product' !== (string) $post->post_type ) {
                return;
            }
            if ( ! in_array( (string) $post->post_status, $statuses, true ) ) {
                return;
            }

            $product = wc_get_product( intval( $post->ID ) );
            if ( ! $product ) {
                return;
            }

            $target           = $this->build_product_target( $post, $product );
            $target['score']  = $this->score_product_match( $query, $target, $statuses );
            $found[]          = $target;
            $seen[ $target['post_id'] ] = true;
        };

        if ( ctype_digit( $query ) ) {
            $add_post( get_post( intval( $query ) ) );
        }

        if ( function_exists( 'wc_get_product_id_by_sku' ) ) {
            $sku_id = wc_get_product_id_by_sku( $query );
            if ( $sku_id > 0 ) {
                $add_post( get_post( $sku_id ) );
            }
        }

        $slug_posts = get_posts(
            array(
                'post_type'      => 'product',
                'post_status'    => $statuses,
                'posts_per_page' => min( 10, $scan_limit ),
                'name'           => sanitize_title( $query ),
            )
        );
        foreach ( (array) $slug_posts as $post ) {
            $add_post( $post );
        }

        $search_posts = get_posts(
            array(
                'post_type'      => 'product',
                'post_status'    => $statuses,
                'posts_per_page' => max( 10, $scan_limit ),
                's'              => $query,
            )
        );
        foreach ( (array) $search_posts as $post ) {
            $add_post( $post );
        }

        $sku_posts = get_posts(
            array(
                'post_type'      => 'product',
                'post_status'    => $statuses,
                'posts_per_page' => max( 10, $scan_limit ),
                'meta_query'     => array(
                    array(
                        'key'     => '_sku',
                        'value'   => $query,
                        'compare' => 'LIKE',
                    ),
                ),
            )
        );
        foreach ( (array) $sku_posts as $post ) {
            $add_post( $post );
        }

        // By title LIKE — catches new products that WP search hasn't indexed yet.
        if ( count( $found ) < $scan_limit ) {
            global $wpdb;
            $like_query = '%' . $wpdb->esc_like( $query ) . '%';
            $status_placeholders = implode( ',', array_fill( 0, count( $statuses ), '%s' ) );
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            $title_ids = $wpdb->get_col( $wpdb->prepare(
                "SELECT ID FROM {$wpdb->posts}
                 WHERE post_type = 'product'
                 AND post_status IN ({$status_placeholders})
                 AND post_title LIKE %s
                 LIMIT %d",
                array_merge( $statuses, array( $like_query, max( 10, $scan_limit ) ) )
            ) );
            if ( ! empty( $title_ids ) ) {
                foreach ( $title_ids as $tid ) {
                    $add_post( get_post( intval( $tid ) ) );
                }
            }
        }

        if ( empty( $found ) ) {
            $fallback_posts = get_posts(
                array(
                    'post_type'      => 'product',
                    'post_status'    => $statuses,
                    'posts_per_page' => min( 50, $scan_limit ),
                    'orderby'        => 'date',
                    'order'          => 'DESC',
                )
            );
            foreach ( (array) $fallback_posts as $post ) {
                $add_post( $post );
            }
        }

        usort(
            $found,
            function ( $a, $b ) {
                return intval( isset( $b['score'] ) ? $b['score'] : 0 ) <=> intval( isset( $a['score'] ) ? $a['score'] : 0 );
            }
        );

        // Minimum score threshold: require at least 25 points to be considered
        // a valid match.  This prevents completely unrelated products from
        // appearing in results.
        $found = array_values(
            array_filter(
                $found,
                function ( $target ) {
                    return intval( isset( $target['score'] ) ? $target['score'] : 0 ) >= 25;
                }
            )
        );

        return $this->slice_filtered_product_targets( $found, $reference );
    }

    private function resolve_best_product_via_target_resolver( $query, $statuses = array() ) {
        if ( ! $this->product_target_resolver || ! method_exists( $this->product_target_resolver, 'resolve_best_product' ) ) {
            return array();
        }

        $resolved = $this->product_target_resolver->resolve_best_product(
            $query,
            $this->normalize_product_statuses( $statuses ),
            $this->get_product_target_resolver_context()
        );
        if ( empty( $resolved['post_id'] ) ) {
            return array();
        }

        return $this->hydrate_resolved_product_target( $resolved );
    }

    private function resolve_products_via_target_resolver( $query, $statuses = array(), $limit = 5 ) {
        if ( ! $this->product_target_resolver || ! method_exists( $this->product_target_resolver, 'resolve_products' ) ) {
            return array();
        }

        $resolved = $this->product_target_resolver->resolve_products(
            $query,
            $this->normalize_product_statuses( $statuses ),
            $limit,
            $this->get_product_target_resolver_context()
        );
        if ( empty( $resolved ) || ! is_array( $resolved ) ) {
            return array();
        }

        $products = array();
        foreach ( $resolved as $candidate ) {
            $target = $this->hydrate_resolved_product_target( $candidate );
            if ( empty( $target['post_id'] ) ) {
                continue;
            }
            $products[] = $target;
        }

        return $products;
    }

    private function hydrate_resolved_product_target( $candidate ) {
        $post_id = isset( $candidate['post_id'] ) ? intval( $candidate['post_id'] ) : 0;
        if ( $post_id <= 0 ) {
            return array();
        }

        $post    = get_post( $post_id );
        $product = wc_get_product( $post_id );
        if ( ! $post || 'product' !== (string) $post->post_type || ! $product ) {
            return array();
        }

        $target = $this->build_product_target( $post, $product );
        foreach ( array( 'score', 'source', 'match_confidence', 'match_warning', 'candidates' ) as $key ) {
            if ( array_key_exists( $key, $candidate ) ) {
                $target[ $key ] = $candidate[ $key ];
            }
        }

        return $target;
    }

    private function resolve_product_target_for_write( $product_id, $product_query, $statuses = array(), $context_label = 'proizvod' ) {
        $product_id    = intval( $product_id );
        $product_query = trim( (string) $product_query );
        $statuses      = $this->normalize_product_statuses( $statuses );
        $context_label = '' !== trim( (string) $context_label ) ? trim( (string) $context_label ) : 'proizvod';

        if ( $product_id > 0 ) {
            $post = get_post( $product_id );
            if ( $post && 'product' === (string) $post->post_type && function_exists( 'wc_get_product' ) ) {
                if ( ! in_array( (string) $post->post_status, $statuses, true ) ) {
                    return array(
                        'success' => false,
                        'error'   => 'Woo proizvod #' . $product_id . ' nije u dozvoljenom statusu za ovu izmenu.',
                    );
                }

                $product = wc_get_product( $product_id );
                if ( $product ) {
                    $target = $this->build_product_target( $post, $product );
                    $target['exact_match']      = true;
                    $target['match_confidence'] = 'high';
                    $target['source']           = 'exact_id';

                    return array(
                        'success'    => true,
                        'target'     => $target,
                        'product_id' => $product_id,
                    );
                }
            }

            return array(
                'success' => false,
                'error'   => 'Nisam nasao Woo proizvod za product_id: ' . $product_id,
            );
        }

        if ( '' === $product_query ) {
            return array(
                'success' => false,
                'error'   => 'Treba mi product_id, sku:..., tacan naslov ili dovoljno jednoznacan product_query za ' . $context_label . '.',
            );
        }

        $numeric_catalog_target = $this->resolve_numeric_catalog_product_target_for_write( $product_query, $statuses, $context_label );
        if ( ! empty( $numeric_catalog_target ) ) {
            return $numeric_catalog_target;
        }

        $matches = $this->find_exact_write_product_targets_by_query( $product_query, $statuses );
        if ( 1 === count( $matches ) ) {
            $target = $matches[0];
            $target['exact_match']      = true;
            $target['match_confidence'] = 'high';

            return array(
                'success'    => true,
                'target'     => $target,
                'product_id' => intval( $target['post_id'] ),
            );
        }

        if ( count( $matches ) > 1 ) {
            return array(
                'success'    => false,
                'error'      => 'Nasao sam vise exact proizvoda za "' . $product_query . '". Za write koristi product_id.',
                'candidates' => $this->format_product_write_candidate_list( $matches ),
            );
        }

        $discriminated = $this->resolve_discriminated_product_target_for_write( $product_query, $statuses );
        if ( ! empty( $discriminated['success'] ) || ! empty( $discriminated['error'] ) ) {
            return $discriminated;
        }

        $semantic = $this->resolve_semantic_product_target_for_write( $product_query, $statuses );
        if ( ! empty( $semantic['success'] ) ) {
            return $semantic;
        }

        $candidate_query = $this->build_semantic_product_candidate_query( $product_query );
        $candidates      = $this->lookup_woo_products( '' !== $candidate_query ? $candidate_query : $product_query, $statuses, 5 );

        return array(
            'success'    => false,
            'error'      => 'Nisam jednoznacno odredio ' . $context_label . ' za "' . $product_query . '". Mogu da pisem samo kad je target precizno zadat ili semanticki jedinstven; inace koristi product_id iz kandidata.',
            'candidates' => $this->format_product_write_candidate_list( $candidates ),
        );
    }

    private function resolve_numeric_catalog_product_target_for_write( $product_query, $statuses = array(), $context_label = 'proizvod' ) {
        $product_query = trim( (string) $product_query );
        if ( '' === $product_query || ! ctype_digit( $product_query ) ) {
            return array();
        }

        $matches = $this->find_products_by_numeric_catalog_reference( $product_query, $statuses, 8, 'title_slug' );
        if ( empty( $matches ) ) {
            $matches = $this->find_products_by_numeric_catalog_reference( $product_query, $statuses, 8, 'sku' );
        }

        if ( 1 === count( $matches ) ) {
            $target = $matches[0];
            $target['exact_match']      = true;
            $target['match_confidence'] = 'high';

            return array(
                'success'    => true,
                'target'     => $target,
                'product_id' => intval( $target['post_id'] ),
            );
        }

        if ( count( $matches ) > 1 ) {
            return array(
                'success'    => false,
                'error'      => 'Nasao sam vise proizvoda za broj/artikal "' . $product_query . '". Za ' . $context_label . ' koristi product_id iz kandidata.',
                'candidates' => $this->format_product_write_candidate_list( $matches ),
            );
        }

        return array(
            'success'    => false,
            'error'      => 'Nisam nasao proizvod ciji naslov, slug ili SKU sadrzi broj/artikal "' . $product_query . '". Ako je ovo Woo ID, koristi product_id:' . $product_query . ' ili prosledi product_id polje.',
            'candidates' => array(),
        );
    }

    private function find_products_by_numeric_catalog_reference( $reference, $statuses = array(), $limit = 8, $scope = 'title_slug' ) {
        if ( ! function_exists( 'wc_get_product' ) ) {
            return array();
        }

        global $wpdb;
        if ( empty( $wpdb ) ) {
            return array();
        }

        $reference = trim( (string) $reference );
        if ( '' === $reference || ! ctype_digit( $reference ) ) {
            return array();
        }

        $statuses = $this->normalize_product_statuses( $statuses );
        $limit    = max( 1, min( 20, intval( $limit ) ) );
        $like     = '%' . $wpdb->esc_like( $reference ) . '%';
        $scope    = in_array( (string) $scope, array( 'title_slug', 'sku' ), true ) ? (string) $scope : 'title_slug';

        $status_placeholders = implode( ',', array_fill( 0, count( $statuses ), '%s' ) );
        if ( 'sku' === $scope ) {
            $match_sql = '(sku.meta_value = %s OR sku.meta_value LIKE %s)';
            $order_sql = 'CASE WHEN sku.meta_value = %s THEN 0 ELSE 1 END, p.post_title ASC';
            $params    = array_merge( $statuses, array( $reference, $like, $reference, $limit ) );
        } else {
            $match_sql = '(p.post_title LIKE %s OR p.post_name LIKE %s)';
            $order_sql = 'CASE WHEN p.post_title LIKE %s THEN 0 ELSE 1 END, p.post_title ASC';
            $params    = array_merge( $statuses, array( $like, $like, $like, $limit ) );
        }

        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        $ids = $wpdb->get_col( $wpdb->prepare(
            "SELECT DISTINCT p.ID
             FROM {$wpdb->posts} p
             LEFT JOIN {$wpdb->postmeta} sku ON (sku.post_id = p.ID AND sku.meta_key = '_sku')
             WHERE p.post_type = 'product'
             AND p.post_status IN ({$status_placeholders})
             AND {$match_sql}
             ORDER BY {$order_sql}
             LIMIT %d",
            $params
        ) );

        $targets = array();
        foreach ( (array) $ids as $id ) {
            $post = get_post( intval( $id ) );
            if ( ! $post || 'product' !== (string) $post->post_type ) {
                continue;
            }

            $product = wc_get_product( intval( $id ) );
            if ( ! $product ) {
                continue;
            }

            $target                     = $this->build_product_target( $post, $product );
            $target['score']            = $this->score_product_match( $reference, $target, $statuses );
            $target['source']           = 'numeric_catalog_' . $scope;
            $target['match_confidence'] = 'high';
            $targets[]                  = $target;
        }

        return $targets;
    }

    private function resolve_discriminated_product_target_for_write( $product_query, $statuses = array() ) {
        $product_query          = trim( (string) $product_query );
        $package_discriminators = $this->extract_product_package_discriminators( $product_query );
        if ( '' === $product_query || empty( $package_discriminators ) ) {
            return array();
        }

        $lookup_terms = $this->build_product_write_lookup_terms( $product_query );
        if ( empty( $lookup_terms ) ) {
            return array();
        }

        $candidates = $this->find_lightweight_products_by_write_terms( $lookup_terms, $statuses, 80 );
        if ( empty( $candidates ) ) {
            return array();
        }

        $matched = array();
        foreach ( $candidates as $candidate ) {
            if ( empty( $candidate['post_id'] ) ) {
                continue;
            }

            $target_text             = $this->build_product_target_search_text( $candidate );
            $target_discriminators   = $this->extract_product_package_discriminators( $target_text );
            $matched_discriminators  = array_intersect( $package_discriminators, $target_discriminators );
            if ( empty( $matched_discriminators ) ) {
                continue;
            }
            if ( ! $this->product_target_matches_lookup_terms( $target_text, $lookup_terms ) ) {
                continue;
            }

            $candidate['score']  = 220 + ( count( $matched_discriminators ) * 40 ) + count( $lookup_terms );
            $candidate['source'] = 'deterministic_discriminator';
            $matched[]           = $candidate;
        }

        if ( 1 === count( $matched ) ) {
            $target = $this->hydrate_resolved_product_target( $matched[0] );
            if ( empty( $target ) ) {
                return array();
            }

            $target['exact_match']      = false;
            $target['match_confidence'] = 'high';
            $target['source']           = 'deterministic_discriminator';

            return array(
                'success'    => true,
                'target'     => $target,
                'product_id' => intval( $target['post_id'] ),
            );
        }

        if ( count( $matched ) > 1 ) {
            return array(
                'success'    => false,
                'error'      => 'Vise proizvoda jednoznacno sadrzi trazenu meru za "' . $product_query . '". Za write koristi product_id.',
                'candidates' => $this->format_product_write_candidate_list( $matched ),
            );
        }

        return array();
    }

    private function build_product_write_lookup_terms( $query ) {
        $tokens = $this->normalize_product_search_tokens( $query );
        if ( empty( $tokens ) ) {
            return array();
        }

        $noise = array(
            'najvec', 'najveca', 'najveci', 'najvece', 'najmanj', 'najmanja', 'najmanji', 'najmanje',
            'najskuplj', 'najskuplja', 'najskuplji', 'najskuplje', 'najjeftinij', 'najjeftinija', 'najjeftiniji', 'najjeftinije',
            'veca', 'veci', 'vece', 'manja', 'manji', 'manje', 'kesa', 'kes', 'pakovanj', 'paket', 'velicin', 'gramaz',
            'proizvod', 'artikl', 'stavk', 'sajt', 'shop', 'radnj', 'sklon', 'skini', 'makni', 'uklon', 'draft',
            'stanj', 'stock', 'lager', 'komad', 'kom', 'sa', 'na', 'iz', 'u', 'za', 'od', 'do', 'the', 'a', 'an',
            'g', 'gr', 'gram', 'grama', 'kg', 'kilogram', 'kilograma', 'ml', 'l', 'lit', 'litar', 'litra', 'litre',
        );

        $terms = array();
        foreach ( $tokens as $token ) {
            $token = trim( (string) $token );
            if ( '' === $token ) {
                continue;
            }
            if ( preg_match( '/\d/', $token ) ) {
                continue;
            }
            if ( in_array( $token, $noise, true ) ) {
                continue;
            }
            $terms[] = $token;
        }

        return array_values( array_unique( $terms ) );
    }

    private function find_lightweight_products_by_write_terms( $lookup_terms, $statuses = array(), $limit = 80 ) {
        global $wpdb;

        if ( empty( $wpdb ) || empty( $lookup_terms ) ) {
            return array();
        }

        $statuses = $this->normalize_product_statuses( $statuses );
        $limit    = max( 1, min( 200, intval( $limit ) ) );

        $status_placeholders = implode( ',', array_fill( 0, count( $statuses ), '%s' ) );
        $where               = array(
            "p.post_type = 'product'",
            "p.post_status IN ({$status_placeholders})",
        );
        $params              = $statuses;

        foreach ( array_slice( $lookup_terms, 0, 5 ) as $term ) {
            $like    = '%' . $wpdb->esc_like( (string) $term ) . '%';
            $where[] = '(p.post_title LIKE %s OR p.post_name LIKE %s OR sku.meta_value LIKE %s)';
            $params[] = $like;
            $params[] = $like;
            $params[] = $like;
        }

        $params[] = $limit;
        $sql      = "SELECT DISTINCT p.ID, p.post_title, p.post_status, p.post_name, COALESCE(sku.meta_value, '') AS sku, COALESCE(weight.meta_value, '') AS weight
            FROM {$wpdb->posts} p
            LEFT JOIN {$wpdb->postmeta} sku ON (sku.post_id = p.ID AND sku.meta_key = '_sku')
            LEFT JOIN {$wpdb->postmeta} weight ON (weight.post_id = p.ID AND weight.meta_key = '_weight')
            WHERE " . implode( ' AND ', $where ) . '
            ORDER BY p.post_title ASC
            LIMIT %d';

        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
        $rows = $wpdb->get_results( $wpdb->prepare( $sql, $params ), ARRAY_A );
        if ( empty( $rows ) || ! is_array( $rows ) ) {
            return array();
        }

        $targets = array();
        foreach ( $rows as $row ) {
            $targets[] = array(
                'post_id'     => intval( isset( $row['ID'] ) ? $row['ID'] : 0 ),
                'post_title'  => isset( $row['post_title'] ) ? (string) $row['post_title'] : '',
                'post_status' => isset( $row['post_status'] ) ? (string) $row['post_status'] : '',
                'post_name'   => isset( $row['post_name'] ) ? (string) $row['post_name'] : '',
                'sku'         => isset( $row['sku'] ) ? (string) $row['sku'] : '',
                'weight'      => isset( $row['weight'] ) ? (string) $row['weight'] : '',
                'score'       => 0,
            );
        }

        return $targets;
    }

    private function product_target_matches_lookup_terms( $target_text, $lookup_terms ) {
        if ( empty( $lookup_terms ) ) {
            return false;
        }

        $target_tokens = $this->normalize_product_search_tokens( $target_text );
        foreach ( $lookup_terms as $term ) {
            if ( ! in_array( (string) $term, $target_tokens, true ) ) {
                return false;
            }
        }

        return true;
    }

    private function extract_product_package_discriminators( $text ) {
        $discriminators = $this->extract_product_search_discriminators( $text );
        if ( empty( $discriminators ) ) {
            return array();
        }

        return array_values(
            array_filter(
                $discriminators,
                function ( $item ) {
                    return preg_match( '/^(?:g|ml):/', (string) $item );
                }
            )
        );
    }

    private function resolve_semantic_product_target_for_write( $product_query, $statuses = array() ) {
        $product_query = trim( (string) $product_query );
        if ( '' === $product_query ) {
            return array();
        }

        $candidate_query = $this->build_semantic_product_candidate_query( $product_query );
        $lookup_query    = '' !== $candidate_query ? $candidate_query : $product_query;
        $candidates      = $this->lookup_woo_products( $lookup_query, $statuses, 12 );
        if ( empty( $candidates ) && $lookup_query !== $product_query ) {
            $candidates = $this->lookup_woo_products( $product_query, $statuses, 12 );
        }
        if ( empty( $candidates ) ) {
            return array();
        }

        $query_discriminators = $this->extract_product_search_discriminators( $product_query );
        if ( ! empty( $query_discriminators ) ) {
            $matched = array_values(
                array_filter(
                    $candidates,
                    function ( $candidate ) use ( $query_discriminators ) {
                        $target_discriminators = $this->extract_product_search_discriminators( $this->build_product_target_search_text( $candidate ) );
                        return ! empty( array_intersect( $query_discriminators, $target_discriminators ) );
                    }
                )
            );

            if ( 1 === count( $matched ) ) {
                return $this->build_semantic_write_resolution_result( $matched[0], 'semantic_discriminator' );
            }
            if ( count( $matched ) > 1 ) {
                return array(
                    'success'    => false,
                    'error'      => 'Vise proizvoda odgovara trazenoj meri/broju u query-ju "' . $product_query . '". Za write koristi product_id.',
                    'candidates' => $this->format_product_write_candidate_list( $matched ),
                );
            }
        }

        $intent = $this->detect_product_selection_intent( $product_query );
        if ( '' !== $intent ) {
            $selected = $this->select_product_candidate_by_intent( $candidates, $intent );
            if ( ! empty( $selected['success'] ) ) {
                return $this->build_semantic_write_resolution_result( $selected['target'], $intent );
            }
            if ( ! empty( $selected['error'] ) ) {
                return array(
                    'success'    => false,
                    'error'      => (string) $selected['error'],
                    'candidates' => $this->format_product_write_candidate_list( $candidates ),
                );
            }
        }

        return array();
    }

    private function build_semantic_write_resolution_result( $target, $source ) {
        if ( empty( $target['post_id'] ) ) {
            return array();
        }

        $target['exact_match']      = false;
        $target['match_confidence'] = 'high';
        $target['source']           = (string) $source;

        return array(
            'success'    => true,
            'target'     => $target,
            'product_id' => intval( $target['post_id'] ),
        );
    }

    private function build_semantic_product_candidate_query( $query ) {
        $tokens = $this->normalize_product_search_tokens( $query );
        if ( empty( $tokens ) ) {
            return '';
        }

        $noise = array(
            'najvec', 'najveca', 'najveci', 'najvece', 'najmanj', 'najmanja', 'najmanji', 'najmanje',
            'najskuplj', 'najskuplja', 'najskuplji', 'najskuplje', 'najjeftinij', 'najjeftinija', 'najjeftiniji', 'najjeftinije',
            'veca', 'veci', 'vece', 'manja', 'manji', 'manje', 'kesa', 'kes', 'pakovanj', 'paket', 'velicin', 'gramaz',
            'proizvod', 'artikl', 'stavk', 'sajt', 'sajt', 'shop', 'radnj', 'sklon', 'skini', 'makni', 'uklon', 'draft',
            'stanj', 'stock', 'lager', 'komad', 'kom', 'sa', 'na', 'iz', 'u', 'za', 'od', 'do', 'the', 'a', 'an',
        );

        $terms = array();
        foreach ( $tokens as $token ) {
            if ( preg_match( '/^\d+(?:[.,]\d+)?$/', $token ) ) {
                continue;
            }
            if ( in_array( $token, $noise, true ) ) {
                continue;
            }
            $terms[] = $token;
        }

        return trim( implode( ' ', array_values( array_unique( $terms ) ) ) );
    }

    private function detect_product_selection_intent( $query ) {
        $tokens = $this->normalize_product_search_tokens( $query );
        $text   = ' ' . implode( ' ', $tokens ) . ' ';

        if ( preg_match( '/\b(najvec|najveca|najveci|najvece|veca|veci|vece|largest|biggest)\b/', $text ) ) {
            return 'largest_package';
        }
        if ( preg_match( '/\b(najmanj|najmanja|najmanji|najmanje|manja|manji|manje|smallest)\b/', $text ) ) {
            return 'smallest_package';
        }
        if ( preg_match( '/\b(najskuplj|najskuplja|najskuplji|najskuplje|highest|most_expensive)\b/', $text ) ) {
            return 'highest_price';
        }
        if ( preg_match( '/\b(najjeftinij|najjeftinija|najjeftiniji|najjeftinije|lowest|cheapest)\b/', $text ) ) {
            return 'lowest_price';
        }

        return '';
    }

    private function select_product_candidate_by_intent( $candidates, $intent ) {
        $ranked = array();
        foreach ( (array) $candidates as $candidate ) {
            if ( ! is_array( $candidate ) || empty( $candidate['post_id'] ) ) {
                continue;
            }

            $value = null;
            if ( in_array( $intent, array( 'largest_package', 'smallest_package' ), true ) ) {
                $value = $this->get_product_candidate_package_value( $candidate );
            } elseif ( in_array( $intent, array( 'highest_price', 'lowest_price' ), true ) ) {
                $price = isset( $candidate['price'] ) && '' !== (string) $candidate['price'] ? (string) $candidate['price'] : ( isset( $candidate['regular_price'] ) ? (string) $candidate['regular_price'] : '' );
                if ( is_numeric( $price ) ) {
                    $value = floatval( $price );
                }
            }

            if ( null === $value ) {
                continue;
            }

            $ranked[] = array(
                'target' => $candidate,
                'value'  => floatval( $value ),
            );
        }

        if ( empty( $ranked ) ) {
            return array();
        }

        usort(
            $ranked,
            function ( $left, $right ) use ( $intent ) {
                $cmp = floatval( $right['value'] ) <=> floatval( $left['value'] );
                if ( in_array( $intent, array( 'smallest_package', 'lowest_price' ), true ) ) {
                    $cmp = -$cmp;
                }
                return 0 !== $cmp ? $cmp : intval( $right['target']['score'] ?? 0 ) <=> intval( $left['target']['score'] ?? 0 );
            }
        );

        if ( ! empty( $ranked[1] ) && abs( floatval( $ranked[0]['value'] ) - floatval( $ranked[1]['value'] ) ) < 0.00001 ) {
            return array( 'success' => false, 'error' => 'Selection intent "' . $intent . '" nije jedinstven: vise proizvoda ima istu vrednost.' );
        }

        return array(
            'success' => true,
            'target'  => $ranked[0]['target'],
        );
    }

    private function get_product_candidate_package_value( $candidate ) {
        $text = $this->build_product_target_search_text( $candidate );
        if ( preg_match_all( '/\b(\d+(?:[.,]\d+)?)\s*(kg|kilogram(?:a)?|g|gr|gram(?:a)?|ml|l|lit(?:ar|ra|re)?|kom|komad(?:a)?|pcs)\b/u', remove_accents( strtolower( $text ) ), $matches, PREG_SET_ORDER ) ) {
            $best = null;
            foreach ( $matches as $match ) {
                $value = floatval( str_replace( ',', '.', (string) $match[1] ) );
                $unit  = (string) $match[2];
                if ( $value <= 0 ) {
                    continue;
                }
                if ( in_array( $unit, array( 'kg', 'kilogram', 'kilograma', 'l', 'lit', 'litar', 'litra', 'litre' ), true ) ) {
                    $value *= 1000;
                }
                $best = null === $best ? $value : max( $best, $value );
            }

            return $best;
        }

        if ( ! empty( $candidate['weight'] ) && is_numeric( $candidate['weight'] ) ) {
            return floatval( $candidate['weight'] );
        }

        return null;
    }

    private function build_product_target_search_text( $target ) {
        if ( ! is_array( $target ) ) {
            return '';
        }

        return trim(
            implode(
                ' ',
                array(
                    isset( $target['post_title'] ) ? (string) $target['post_title'] : '',
                    isset( $target['post_name'] ) ? (string) $target['post_name'] : '',
                    isset( $target['sku'] ) ? (string) $target['sku'] : '',
                    isset( $target['weight'] ) ? (string) $target['weight'] : '',
                )
            )
        );
    }

    private function find_direct_product_identity_matches_by_query( $query, $statuses = array(), $limit = 5 ) {
        $query    = trim( (string) $query );
        $limit    = max( 1, min( 20, intval( $limit ) ) );
        $statuses = $this->normalize_product_statuses( $statuses );
        if ( '' === $query ) {
            return array();
        }

        $matches = array();
        $seen    = array();
        $add_target = function ( $target ) use ( &$matches, &$seen, $statuses, $limit ) {
            if ( empty( $target['post_id'] ) ) {
                return;
            }

            $post_id = intval( $target['post_id'] );
            if ( $post_id <= 0 || isset( $seen[ $post_id ] ) || count( $matches ) >= $limit ) {
                return;
            }
            if ( ! empty( $statuses ) && ! in_array( (string) ( isset( $target['post_status'] ) ? $target['post_status'] : '' ), $statuses, true ) ) {
                return;
            }

            $target['exact_match']      = true;
            $target['match_confidence'] = 'high';
            $matches[]                  = $target;
            $seen[ $post_id ]           = true;
        };

        if ( ctype_digit( $query ) ) {
            $target = $this->hydrate_resolved_product_target(
                array(
                    'post_id' => intval( $query ),
                    'score'   => 200,
                    'source'  => 'exact_id',
                )
            );
            if ( ! empty( $target ) ) {
                $add_target( $target );
            }
        }

        if ( function_exists( 'wc_get_product_id_by_sku' ) ) {
            $sku_id = intval( wc_get_product_id_by_sku( $query ) );
            if ( $sku_id > 0 ) {
                $target = $this->hydrate_resolved_product_target(
                    array(
                        'post_id' => $sku_id,
                        'score'   => 200,
                        'source'  => 'exact_sku',
                    )
                );
                if ( ! empty( $target ) ) {
                    $add_target( $target );
                }
            }
        }

        foreach ( $this->find_products_by_exact_title_or_slug( $query, $statuses, $limit ) as $target ) {
            $add_target( $target );
        }

        return $matches;
    }

    private function find_exact_write_product_targets_by_query( $query, $statuses = array() ) {
        $query    = trim( (string) $query );
        $statuses = $this->normalize_product_statuses( $statuses );
        if ( '' === $query ) {
            return array();
        }

        $reference = $this->parse_product_lookup_reference( $query );
        if ( ! empty( $reference['exact_only'] ) ) {
            return $this->find_exact_products_by_query( $query, $statuses, 5 );
        }

        $matches = array();
        $seen    = array();
        $add_target = function ( $target ) use ( &$matches, &$seen, $statuses ) {
            if ( empty( $target['post_id'] ) ) {
                return;
            }

            $post_id = intval( $target['post_id'] );
            if ( $post_id <= 0 || isset( $seen[ $post_id ] ) ) {
                return;
            }
            if ( ! empty( $statuses ) && ! in_array( (string) ( isset( $target['post_status'] ) ? $target['post_status'] : '' ), $statuses, true ) ) {
                return;
            }

            $target['exact_match']      = true;
            $target['match_confidence'] = 'high';
            $matches[]                  = $target;
            $seen[ $post_id ]           = true;
        };

        if ( ctype_digit( $query ) ) {
            $target = $this->hydrate_resolved_product_target(
                array(
                    'post_id' => intval( $query ),
                    'score'   => 200,
                    'source'  => 'exact_id',
                )
            );
            if ( ! empty( $target ) ) {
                $add_target( $target );
            }
        }

        if ( function_exists( 'wc_get_product_id_by_sku' ) ) {
            $sku_id = intval( wc_get_product_id_by_sku( $query ) );
            if ( $sku_id > 0 ) {
                $target = $this->hydrate_resolved_product_target(
                    array(
                        'post_id' => $sku_id,
                        'score'   => 200,
                        'source'  => 'exact_sku',
                    )
                );
                if ( ! empty( $target ) ) {
                    $add_target( $target );
                }
            }
        }

        foreach ( $this->find_products_by_exact_title_or_slug( $query, $statuses, 5 ) as $target ) {
            $add_target( $target );
        }

        return $matches;
    }

    private function format_product_write_candidate_list( $candidates ) {
        $formatted = array();
        foreach ( (array) $candidates as $candidate ) {
            if ( ! is_array( $candidate ) || empty( $candidate['post_id'] ) ) {
                continue;
            }

            $formatted[] = array(
                'product_id'  => intval( $candidate['post_id'] ),
                'post_title'  => isset( $candidate['post_title'] ) ? (string) $candidate['post_title'] : '',
                'post_status' => isset( $candidate['post_status'] ) ? (string) $candidate['post_status'] : '',
                'sku'         => isset( $candidate['sku'] ) ? (string) $candidate['sku'] : '',
                'score'       => isset( $candidate['score'] ) ? $candidate['score'] : 0,
            );

            if ( count( $formatted ) >= 5 ) {
                break;
            }
        }

        return $formatted;
    }

    private function get_product_target_resolver_context() {
        return isset( $this->runtime_context ) && is_array( $this->runtime_context ) ? $this->runtime_context : array();
    }

    private function list_catalog_products_by_statuses( $statuses, $limit, $reference = array() ) {
        $statuses = $this->normalize_product_statuses( $statuses );
        $limit    = max( 1, min( 1000, intval( $limit ) ) );
        $posts    = get_posts(
            array(
                'post_type'              => 'product',
                'post_status'            => $statuses,
                'posts_per_page'         => $limit,
                'orderby'                => 'date',
                'order'                  => 'DESC',
                'no_found_rows'          => true,
                'update_post_term_cache' => false,
                'update_post_meta_cache' => false,
            )
        );
        $items    = array();

        foreach ( (array) $posts as $post ) {
            $product = wc_get_product( intval( $post->ID ) );
            if ( ! $product ) {
                continue;
            }

            $target          = $this->build_product_target( $post, $product );
            $target['score'] = 50;
            $items[]         = $target;
        }

        return $this->slice_filtered_product_targets( $items, $reference );
    }

    private function slice_filtered_product_targets( $targets, $reference = array() ) {
        $targets = is_array( $targets ) ? array_values( $targets ) : array();
        if ( empty( $targets ) ) {
            return array();
        }

        $reference = is_array( $reference ) ? $reference : array();
        $filtered  = array_values(
            array_filter(
                $targets,
                function ( $target ) use ( $reference ) {
                    return $this->product_target_matches_lookup_filters( $target, $reference );
                }
            )
        );

        $limit  = max( 1, min( 50, intval( isset( $reference['lookup_limit'] ) ? $reference['lookup_limit'] : 5 ) ) );
        $offset = max( 0, intval( isset( $reference['offset'] ) ? $reference['offset'] : 0 ) );

        return array_slice( $filtered, $offset, $limit );
    }

    private function product_target_matches_lookup_filters( $target, $reference ) {
        if ( ! is_array( $target ) ) {
            return false;
        }

        if ( ! empty( $reference['onsale_only'] ) && empty( $target['is_on_sale'] ) ) {
            return false;
        }

        $exclude_category_id   = intval( isset( $reference['exclude_category_id'] ) ? $reference['exclude_category_id'] : 0 );
        $exclude_category_slug = sanitize_title( isset( $reference['exclude_category_slug'] ) ? (string) $reference['exclude_category_slug'] : '' );
        $category_ids          = isset( $target['category_ids'] ) && is_array( $target['category_ids'] ) ? array_map( 'intval', $target['category_ids'] ) : array();
        $category_slugs        = isset( $target['category_slugs'] ) && is_array( $target['category_slugs'] ) ? array_map( 'sanitize_title', $target['category_slugs'] ) : array();

        if ( $exclude_category_id > 0 && in_array( $exclude_category_id, $category_ids, true ) ) {
            return false;
        }

        if ( '' !== $exclude_category_slug && in_array( $exclude_category_slug, $category_slugs, true ) ) {
            return false;
        }

        return true;
    }

    private function build_product_target( $post, $product ) {
        $pid = intval( $post->ID );

        /* Categories and tags. */
        $cat_terms = wp_get_object_terms( $pid, 'product_cat' );
        $tag_terms = wp_get_object_terms( $pid, 'product_tag', array( 'fields' => 'names' ) );
        $category_names = array();
        $category_ids   = array();
        $category_slugs = array();
        if ( is_array( $cat_terms ) ) {
            foreach ( $cat_terms as $term ) {
                if ( ! is_object( $term ) || empty( $term->term_id ) ) {
                    continue;
                }
                $category_names[] = (string) $term->name;
                $category_ids[]   = intval( $term->term_id );
                $category_slugs[] = (string) $term->slug;
            }
        }

        /* Dimensions string. */
        $dims = '';
        if ( method_exists( $product, 'get_length' ) ) {
            $l = (string) $product->get_length();
            $w = method_exists( $product, 'get_width' ) ? (string) $product->get_width() : '';
            $h = method_exists( $product, 'get_height' ) ? (string) $product->get_height() : '';
            $parts = array_filter( array( $l, $w, $h ), 'strlen' );
            if ( ! empty( $parts ) ) {
                $dims = implode( ' x ', $parts );
            }
        }

        $featured_image_id = method_exists( $product, 'get_image_id' ) ? intval( $product->get_image_id() ) : 0;
        $featured_image_url = $featured_image_id > 0 && function_exists( 'wp_get_attachment_image_url' )
            ? (string) wp_get_attachment_image_url( $featured_image_id, 'full' )
            : '';
        $gallery_image_ids = method_exists( $product, 'get_gallery_image_ids' )
            ? array_values( array_filter( array_map( 'intval', (array) $product->get_gallery_image_ids() ) ) )
            : array();
        $gallery_image_urls = array();
        if ( function_exists( 'wp_get_attachment_image_url' ) ) {
            foreach ( $gallery_image_ids as $gallery_image_id ) {
                $gallery_image_url = wp_get_attachment_image_url( $gallery_image_id, 'full' );
                if ( is_string( $gallery_image_url ) && '' !== $gallery_image_url ) {
                    $gallery_image_urls[] = $gallery_image_url;
                }
            }
        }

        return array(
            'post_id'            => $pid,
            'post_title'         => (string) $post->post_title,
            'post_status'        => (string) $post->post_status,
            'post_name'          => (string) $post->post_name,
            'description'        => method_exists( $product, 'get_description' ) ? (string) $product->get_description() : (string) $post->post_content,
            'short_description'  => method_exists( $product, 'get_short_description' ) ? (string) $product->get_short_description() : (string) $post->post_excerpt,
            'featured_image_id'  => $featured_image_id,
            'featured_image_url' => $featured_image_url,
            'gallery_image_ids'  => $gallery_image_ids,
            'gallery_image_urls' => $gallery_image_urls,
            'product_type'       => method_exists( $product, 'get_type' ) ? (string) $product->get_type() : '',
            'sku'                => method_exists( $product, 'get_sku' ) ? (string) $product->get_sku() : '',
            'regular_price'      => method_exists( $product, 'get_regular_price' ) ? (string) $product->get_regular_price() : '',
            'regular_price_display' => $this->format_price_display_value( method_exists( $product, 'get_regular_price' ) ? (string) $product->get_regular_price() : '' ),
            'sale_price'         => method_exists( $product, 'get_sale_price' ) ? (string) $product->get_sale_price() : '',
            'sale_price_display' => $this->format_price_display_value( method_exists( $product, 'get_sale_price' ) ? (string) $product->get_sale_price() : '' ),
            'date_on_sale_from'  => method_exists( $product, 'get_date_on_sale_from' ) && method_exists( $this, 'format_wc_datetime_for_tool' ) ? $this->format_wc_datetime_for_tool( $product->get_date_on_sale_from( 'edit' ) ) : '',
            'date_on_sale_to'    => method_exists( $product, 'get_date_on_sale_to' ) && method_exists( $this, 'format_wc_datetime_for_tool' ) ? $this->format_wc_datetime_for_tool( $product->get_date_on_sale_to( 'edit' ) ) : '',
            'price'              => method_exists( $product, 'get_price' ) ? (string) $product->get_price() : '',
            'price_display'      => $this->format_price_display_value( method_exists( $product, 'get_price' ) ? (string) $product->get_price() : '' ),
            'is_on_sale'         => method_exists( $product, 'is_on_sale' ) ? ( $product->is_on_sale() ? 1 : 0 ) : 0,
            'manage_stock'       => method_exists( $product, 'get_manage_stock' ) ? ( $product->get_manage_stock() ? 1 : 0 ) : 0,
            'stock_quantity'     => method_exists( $product, 'get_stock_quantity' ) ? $product->get_stock_quantity() : null,
            'stock_status'       => method_exists( $product, 'get_stock_status' ) ? (string) $product->get_stock_status() : '',
            'weight'             => method_exists( $product, 'get_weight' ) ? (string) $product->get_weight() : '',
            'dimensions'         => $dims,
            'categories'         => $category_names,
            'category_ids'       => array_values( array_unique( $category_ids ) ),
            'category_slugs'     => array_values( array_unique( $category_slugs ) ),
            'tags'               => is_array( $tag_terms ) ? $tag_terms : array(),
            'catalog_visibility' => method_exists( $product, 'get_catalog_visibility' ) ? (string) $product->get_catalog_visibility() : '',
            'featured'           => method_exists( $product, 'get_featured' ) ? ( $product->get_featured() ? 1 : 0 ) : 0,
            'virtual'            => method_exists( $product, 'get_virtual' ) ? ( $product->get_virtual() ? 1 : 0 ) : 0,
            'downloadable'       => method_exists( $product, 'get_downloadable' ) ? ( $product->get_downloadable() ? 1 : 0 ) : 0,
            'tax_status'         => method_exists( $product, 'get_tax_status' ) ? (string) $product->get_tax_status() : '',
            'sold_individually'  => method_exists( $product, 'get_sold_individually' ) ? ( $product->get_sold_individually() ? 1 : 0 ) : 0,
            'backorders'         => method_exists( $product, 'get_backorders' ) ? (string) $product->get_backorders() : '',
            'score'              => 0,
            'exact_match'        => false,
        );
    }

    private function build_variation_bulk_target( $variation, $parent_post ) {
        $attributes = method_exists( $variation, 'get_variation_attributes' ) ? (array) $variation->get_variation_attributes() : array();
        $label      = get_the_title( intval( $parent_post->ID ) );
        if ( ! empty( $attributes ) ) {
            $label .= ' - ' . $this->format_variation_meta_for_summary( $attributes );
        }

        return array(
            'kind'           => 'variation',
            'variation_id'   => intval( $variation->get_id() ),
            'parent_id'      => intval( $parent_post->ID ),
            'post_id'        => intval( $parent_post->ID ),
            'post_title'     => (string) $parent_post->post_title,
            'post_status'    => (string) $parent_post->post_status,
            'product_type'   => 'variation',
            'sku'            => method_exists( $variation, 'get_sku' ) ? (string) $variation->get_sku() : '',
            'regular_price'  => method_exists( $variation, 'get_regular_price' ) ? (string) $variation->get_regular_price() : '',
            'regular_price_display' => $this->format_price_display_value( method_exists( $variation, 'get_regular_price' ) ? (string) $variation->get_regular_price() : '' ),
            'sale_price'     => method_exists( $variation, 'get_sale_price' ) ? (string) $variation->get_sale_price() : '',
            'sale_price_display' => $this->format_price_display_value( method_exists( $variation, 'get_sale_price' ) ? (string) $variation->get_sale_price() : '' ),
            'date_on_sale_from' => method_exists( $variation, 'get_date_on_sale_from' ) && method_exists( $this, 'format_wc_datetime_for_tool' ) ? $this->format_wc_datetime_for_tool( $variation->get_date_on_sale_from( 'edit' ) ) : '',
            'date_on_sale_to' => method_exists( $variation, 'get_date_on_sale_to' ) && method_exists( $this, 'format_wc_datetime_for_tool' ) ? $this->format_wc_datetime_for_tool( $variation->get_date_on_sale_to( 'edit' ) ) : '',
            'price'          => method_exists( $variation, 'get_price' ) ? (string) $variation->get_price() : '',
            'price_display'  => $this->format_price_display_value( method_exists( $variation, 'get_price' ) ? (string) $variation->get_price() : '' ),
            'stock_quantity' => method_exists( $variation, 'get_stock_quantity' ) ? $variation->get_stock_quantity() : null,
            'stock_status'   => method_exists( $variation, 'get_stock_status' ) ? (string) $variation->get_stock_status() : '',
            'target_label'   => $label,
            'attributes'     => $attributes,
            'exact_match'    => false,
        );
    }

    private function score_product_match( $query, $target, $statuses ) {
        $query_lc = strtolower( trim( (string) $query ) );
        $score    = 0;

        $title = strtolower( isset( $target['post_title'] ) ? (string) $target['post_title'] : '' );
        $slug  = strtolower( isset( $target['post_name'] ) ? (string) $target['post_name'] : '' );
        $sku   = strtolower( isset( $target['sku'] ) ? (string) $target['sku'] : '' );
        $query_tokens = $this->normalize_product_search_tokens( $query );
        $title_tokens = $this->normalize_product_search_tokens( $title );
        $slug_tokens  = $this->normalize_product_search_tokens( $slug );
        $sku_tokens   = $this->normalize_product_search_tokens( $sku );
        $query_discriminators = $this->extract_product_search_discriminators( $query );
        $target_discriminators = $this->extract_product_search_discriminators( trim( $title . ' ' . $slug . ' ' . $sku ) );

        if ( '' !== $query_lc && $query_lc === $title ) {
            $score += 120;
        } elseif ( '' !== $query_lc && false !== strpos( $title, $query_lc ) ) {
            $score += 80;
        }

        if ( '' !== $query_lc && $query_lc === $slug ) {
            $score += 100;
        } elseif ( '' !== $query_lc && false !== strpos( $slug, sanitize_title( $query_lc ) ) ) {
            $score += 60;
        }

        if ( '' !== $query_lc && $query_lc === $sku ) {
            $score += 110;
        } elseif ( '' !== $query_lc && '' !== $sku && false !== strpos( $sku, $query_lc ) ) {
            $score += 70;
        }

        if ( ! empty( $query_tokens ) ) {
            $title_overlap = count( array_intersect( $query_tokens, $title_tokens ) );
            $slug_overlap  = count( array_intersect( $query_tokens, $slug_tokens ) );
            $sku_overlap   = count( array_intersect( $query_tokens, $sku_tokens ) );

            if ( $title_overlap > 0 ) {
                $score += $title_overlap * 28;
            }
            if ( $slug_overlap > 0 ) {
                $score += $slug_overlap * 16;
            }
            if ( $sku_overlap > 0 ) {
                $score += $sku_overlap * 20;
            }
        }

        if ( ! empty( $query_discriminators ) ) {
            $discriminator_overlap = array_intersect( $query_discriminators, $target_discriminators );
            if ( ! empty( $discriminator_overlap ) ) {
                $score += count( $discriminator_overlap ) * 90;
            } elseif ( ! empty( $target_discriminators ) ) {
                $score -= 160;
            }
        }

        $status       = isset( $target['post_status'] ) ? (string) $target['post_status'] : '';
        $status_index = array_search( $status, $statuses, true );
        if ( false !== $status_index ) {
            $score += max( 0, 30 - ( intval( $status_index ) * 3 ) );
        }

        return $score;
    }

    private function extract_product_search_discriminators( $text ) {
        $text = remove_accents( strtolower( trim( (string) $text ) ) );
        if ( '' === $text ) {
            return array();
        }

        $discriminators = array();
        if ( preg_match_all( '/\b(\d+(?:[.,]\d+)?)\s*(kg|kilogram(?:a)?|g|gr|gram(?:a)?|ml|l|lit(?:ar|ra|re)?|kom|komad(?:a)?|pcs)\b/u', $text, $matches, PREG_SET_ORDER ) ) {
            foreach ( $matches as $match ) {
                $number = str_replace( ',', '.', (string) $match[1] );
                $unit   = (string) $match[2];
                $value  = floatval( $number );
                if ( $value <= 0 ) {
                    continue;
                }

                if ( in_array( $unit, array( 'kg', 'kilogram', 'kilograma' ), true ) ) {
                    $discriminators[] = 'g:' . $this->normalize_product_discriminator_number( $value * 1000 );
                } elseif ( in_array( $unit, array( 'g', 'gr', 'gram', 'grama' ), true ) ) {
                    $discriminators[] = 'g:' . $this->normalize_product_discriminator_number( $value );
                } elseif ( in_array( $unit, array( 'l', 'lit', 'litar', 'litra', 'litre' ), true ) ) {
                    $discriminators[] = 'ml:' . $this->normalize_product_discriminator_number( $value * 1000 );
                } elseif ( 'ml' === $unit ) {
                    $discriminators[] = 'ml:' . $this->normalize_product_discriminator_number( $value );
                } else {
                    $discriminators[] = 'qty:' . $this->normalize_product_discriminator_number( $value );
                }

                $discriminators[] = 'num:' . $this->normalize_product_discriminator_number( $value );
            }
        }

        if ( preg_match_all( '/\b\d+(?:[.,]\d+)?\b/u', $text, $number_matches ) ) {
            foreach ( (array) $number_matches[0] as $number ) {
                $value = floatval( str_replace( ',', '.', (string) $number ) );
                if ( $value > 0 ) {
                    $discriminators[] = 'num:' . $this->normalize_product_discriminator_number( $value );
                }
            }
        }

        return array_values( array_unique( $discriminators ) );
    }

    private function normalize_product_discriminator_number( $value ) {
        $value = floatval( $value );
        if ( abs( $value - round( $value ) ) < 0.00001 ) {
            return (string) intval( round( $value ) );
        }

        return rtrim( rtrim( number_format( $value, 4, '.', '' ), '0' ), '.' );
    }

    private function normalize_product_search_tokens( $text ) {
        $text = remove_accents( strtolower( trim( (string) $text ) ) );
        if ( '' === $text ) {
            return array();
        }

        $text   = preg_replace( '/[^a-z0-9]+/i', ' ', $text );
        $tokens = preg_split( '/\s+/', trim( (string) $text ) );
        if ( ! is_array( $tokens ) ) {
            return array();
        }

        $normalized = array();
        foreach ( $tokens as $token ) {
            $token = trim( (string) $token );
            if ( '' === $token ) {
                continue;
            }
            if ( strlen( $token ) > 3 ) {
                $token = $this->stem_product_search_token( $token );
            }
            $normalized[] = $token;
        }

        return array_values( array_unique( array_filter( $normalized ) ) );
    }

    private function stem_product_search_token( $token ) {
        $token = trim( strtolower( (string) $token ) );
        foreach ( array( 'ovima', 'evima', 'ovima', 'ovima', 'ovima', 'ima', 'ama', 'ovima', 'ovi', 'eve', 'ove', 'ima', 'ama', 'om', 'em', 'og', 'eg', 'ih', 'ah', 'uh', 'a', 'e', 'i', 'o', 'u' ) as $suffix ) {
            if ( strlen( $token ) <= strlen( $suffix ) + 2 ) {
                continue;
            }
            if ( str_ends_with( $token, $suffix ) ) {
                return substr( $token, 0, -strlen( $suffix ) );
            }
        }

        return $token;
    }

    private function normalize_product_statuses( $statuses ) {
        $default = array( 'publish', 'private', 'draft', 'pending', 'future', 'trash' );
        if ( empty( $statuses ) || ! is_array( $statuses ) ) {
            return $default;
        }

        $normalized = array();
        foreach ( $statuses as $status ) {
            $status = sanitize_key( (string) $status );
            if ( in_array( $status, $default, true ) ) {
                $normalized[] = $status;
            }
        }

        return ! empty( $normalized ) ? array_values( array_unique( $normalized ) ) : $default;
    }

    private function normalize_decimal_price( $value ) {
        $value = trim( (string) $value );
        if ( '' === $value ) {
            return null;
        }

        $value = str_replace( array( ' ', "\xc2\xa0" ), '', $value );
        $comma = strrpos( $value, ',' );
        $dot   = strrpos( $value, '.' );

        if ( false !== $comma && false !== $dot ) {
            if ( $comma > $dot ) {
                $value = str_replace( '.', '', $value );
                $value = str_replace( ',', '.', $value );
            } else {
                $value = str_replace( ',', '', $value );
            }
        } elseif ( false !== $comma ) {
            $value = str_replace( ',', '.', $value );
        }

        if ( ! is_numeric( $value ) ) {
            return null;
        }

        return function_exists( 'wc_format_decimal' ) ? wc_format_decimal( $value, wc_get_price_decimals() ) : (string) $value;
    }

    private function normalize_post_type( $post_type ) {
        $post_type = sanitize_key( (string) $post_type );
        return in_array( $post_type, array( 'post', 'page', 'product' ), true ) ? $post_type : 'post';
    }
}
