<?php

namespace MintyPHP\Tests\Unit\Support;

use MintyPHP\Support\Search\SearchQueryNormalizer;
use PHPUnit\Framework\TestCase;

final class SearchQueryNormalizerTest extends TestCase
{
    // ── normalizeLikeQuery ──

    public function testNormalizeLikeQueryReturnsEmptyForBlankInput(): void
    {
        self::assertSame('', SearchQueryNormalizer::normalizeLikeQuery(''));
        self::assertSame('', SearchQueryNormalizer::normalizeLikeQuery('   '));
    }

    public function testNormalizeLikeQueryWrapsWithWildcards(): void
    {
        self::assertSame('%hello%', SearchQueryNormalizer::normalizeLikeQuery('hello'));
    }

    public function testNormalizeLikeQueryDoesNotDoubleWrapLeadingWildcard(): void
    {
        self::assertSame('%hello%', SearchQueryNormalizer::normalizeLikeQuery('*hello'));
    }

    public function testNormalizeLikeQueryDoesNotDoubleWrapTrailingWildcard(): void
    {
        self::assertSame('%hello%', SearchQueryNormalizer::normalizeLikeQuery('hello*'));
    }

    public function testNormalizeLikeQueryDoesNotDoubleWrapBothWildcards(): void
    {
        self::assertSame('%hello%', SearchQueryNormalizer::normalizeLikeQuery('*hello*'));
    }

    public function testNormalizeLikeQueryEscapesBackslash(): void
    {
        self::assertSame('%foo\\\\bar%', SearchQueryNormalizer::normalizeLikeQuery('foo\\bar'));
    }

    public function testNormalizeLikeQueryEscapesUnderscore(): void
    {
        self::assertSame('%foo\\_bar%', SearchQueryNormalizer::normalizeLikeQuery('foo_bar'));
    }

    public function testNormalizeLikeQueryConvertsAsterisksToPercent(): void
    {
        self::assertSame('%foo%bar%', SearchQueryNormalizer::normalizeLikeQuery('foo*bar'));
    }

    public function testNormalizeLikeQueryCombinesEscapingAndWildcards(): void
    {
        // Input: "a_b*c\d" → underscores escaped, * becomes %, backslash escaped, wrapped
        self::assertSame('%a\\_b%c\\\\d%', SearchQueryNormalizer::normalizeLikeQuery('a_b*c\\d'));
    }

    public function testNormalizeLikeQueryTrimsWhitespace(): void
    {
        self::assertSame('%search%', SearchQueryNormalizer::normalizeLikeQuery('  search  '));
    }

    public function testNormalizeLikeQuerySingleCharacter(): void
    {
        self::assertSame('%x%', SearchQueryNormalizer::normalizeLikeQuery('x'));
    }

    public function testNormalizeLikeQueryOnlyWildcard(): void
    {
        self::assertSame('%', SearchQueryNormalizer::normalizeLikeQuery('*'));
    }

    public function testNormalizeLikeQueryMultipleConsecutiveWildcards(): void
    {
        self::assertSame('%a%%%b%', SearchQueryNormalizer::normalizeLikeQuery('a***b'));
    }

    public function testNormalizeLikeQueryUnicodeInput(): void
    {
        self::assertSame('%Ünterström%', SearchQueryNormalizer::normalizeLikeQuery('Ünterström'));
    }

    // ── normalizeScoreQuery ──

    public function testNormalizeScoreQueryReturnsEmptyForBlankInput(): void
    {
        self::assertSame('', SearchQueryNormalizer::normalizeScoreQuery(''));
        self::assertSame('', SearchQueryNormalizer::normalizeScoreQuery('   '));
    }

    public function testNormalizeScoreQueryStripsAsterisks(): void
    {
        self::assertSame('hello', SearchQueryNormalizer::normalizeScoreQuery('*hello*'));
    }

    public function testNormalizeScoreQueryStripsPercent(): void
    {
        self::assertSame('hello', SearchQueryNormalizer::normalizeScoreQuery('%hello%'));
    }

    public function testNormalizeScoreQueryStripsUnderscore(): void
    {
        self::assertSame('foobar', SearchQueryNormalizer::normalizeScoreQuery('foo_bar'));
    }

    public function testNormalizeScoreQueryStripsAllWildcardTypes(): void
    {
        self::assertSame('abc', SearchQueryNormalizer::normalizeScoreQuery('*a%b_c*'));
    }

    public function testNormalizeScoreQueryPreservesNormalText(): void
    {
        self::assertSame('search term', SearchQueryNormalizer::normalizeScoreQuery('search term'));
    }

    public function testNormalizeScoreQueryTrimsWhitespace(): void
    {
        self::assertSame('query', SearchQueryNormalizer::normalizeScoreQuery('  query  '));
    }

    public function testNormalizeScoreQueryOnlyWildcards(): void
    {
        self::assertSame('', SearchQueryNormalizer::normalizeScoreQuery('*%_'));
    }

    public function testNormalizeScoreQueryPreservesBackslash(): void
    {
        self::assertSame('a\\b', SearchQueryNormalizer::normalizeScoreQuery('a\\b'));
    }

    public function testNormalizeScoreQueryUnicodeInput(): void
    {
        self::assertSame('Müller', SearchQueryNormalizer::normalizeScoreQuery('Müller'));
    }
}
