<?php

namespace MintyPHP\Tests\Repository;

use MintyPHP\Repository\Support\RepoQuery;
use PHPUnit\Framework\TestCase;

class RepoQueryTest extends TestCase
{
    public function testSanitizeLimitOffsetDefaults(): void
    {
        [$limit, $offset] = RepoQuery::sanitizeLimitOffset([]);
        $this->assertSame(10, $limit);
        $this->assertSame(0, $offset);
    }

    public function testSanitizeLimitOffsetBounds(): void
    {
        [$limit, $offset] = RepoQuery::sanitizeLimitOffset(['limit' => 0, 'offset' => -5]);
        $this->assertSame(10, $limit);
        $this->assertSame(0, $offset);

        [$limit, $offset] = RepoQuery::sanitizeLimitOffset(['limit' => 999, 'offset' => 5]);
        $this->assertSame(100, $limit);
        $this->assertSame(5, $offset);
    }

    public function testSanitizeOrder(): void
    {
        [$order, $dir] = RepoQuery::sanitizeOrder(['order' => 'name', 'dir' => 'ASC'], ['id', 'name']);
        $this->assertSame('name', $order);
        $this->assertSame('asc', $dir);

        [$order, $dir] = RepoQuery::sanitizeOrder(['order' => 'bad', 'dir' => 'weird'], ['id', 'name']);
        $this->assertSame('id', $order);
        $this->assertSame('desc', $dir);
    }

    public function testAddLikeFilter(): void
    {
        $where = [];
        $params = [];
        RepoQuery::addLikeFilter($where, $params, ['a', 'b'], '');
        $this->assertSame([], $where);
        $this->assertSame([], $params);

        RepoQuery::addLikeFilter($where, $params, ['a', 'b'], 'foo');
        $this->assertSame(["(a like ? escape '\\\\' or b like ? escape '\\\\')"], $where);
        $this->assertSame(['%foo%', '%foo%'], $params);
    }

    public function testAddEnumFilter(): void
    {
        $where = [];
        $params = [];
        RepoQuery::addEnumFilter($where, $params, 'active', [
            ['aliases' => ['active'], 'sql' => 'status = ?', 'params' => ['1']],
        ]);
        $this->assertSame(['status = ?'], $where);
        $this->assertSame(['1'], $params);

        $where = [];
        $params = [];
        RepoQuery::addEnumFilter($where, $params, 'unknown', [
            ['aliases' => ['active'], 'sql' => 'status = ?', 'params' => ['1']],
        ]);
        $this->assertSame([], $where);
        $this->assertSame([], $params);
    }

    public function testAddEqualsFilter(): void
    {
        $where = [];
        $params = [];
        RepoQuery::addEqualsFilter($where, $params, '', 'foo = ?');
        $this->assertSame([], $where);
        $this->assertSame([], $params);

        RepoQuery::addEqualsFilter($where, $params, 'bar', 'foo = ?');
        $this->assertSame(['foo = ?'], $where);
        $this->assertSame(['bar'], $params);
    }

    public function testNormalizeStringList(): void
    {
        $list = RepoQuery::normalizeStringList(' a, b, a ,, c ');
        $this->assertSame(['a', 'b', 'c'], $list);

        $list = RepoQuery::normalizeStringList([' A ', ['B', 'a'], ''], 10, static fn (string $value): string => strtolower($value));
        $this->assertSame(['a', 'b'], $list);

        $list = RepoQuery::normalizeStringList('1,2,3,4', 2);
        $this->assertSame(['1', '2'], $list);
    }
}
