<?php

declare(strict_types=1);

namespace Numinix\SeekmodoSdk\Search;

/**
 * Normalizes storefront search queries before retrieval or gateway calls.
 */
final class QueryNormalizer
{
    private int $minLength;
    private int $maxLength;
    private bool $stripCommerceStopwords;

    /** @var list<string> */
    private array $commerceStopwords = ['the', 'a', 'an', 'for', 'and', 'or'];

    public function __construct(
        int $minLength = 1,
        int $maxLength = 120,
        bool $stripCommerceStopwords = false
    ) {
        $this->minLength = $minLength;
        $this->maxLength = $maxLength;
        $this->stripCommerceStopwords = $stripCommerceStopwords;
    }

    public function normalize(string $q): ?string
    {
        $q = trim(preg_replace('/\s+/u', ' ', $q) ?? '');
        if ($q === '') {
            return null;
        }
        if (mb_strlen($q) < $this->minLength) {
            return null;
        }
        if (mb_strlen($q) > $this->maxLength) {
            $q = mb_substr($q, 0, $this->maxLength);
        }
        if ($this->stripCommerceStopwords) {
            $parts = preg_split('/\s+/u', mb_strtolower($q)) ?: [];
            $filtered = [];
            foreach ($parts as $part) {
                if ($part !== '' && !in_array($part, $this->commerceStopwords, true)) {
                    $filtered[] = $part;
                }
            }
            $q = implode(' ', $filtered);
            if ($q === '') {
                return null;
            }
        }

        return $q;
    }

    public function cacheKey(string $q): string
    {
        return mb_strtolower(trim($q));
    }
}
