<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\Search\Entity;

use Chill\MainBundle\Repository\UserRepository;
use Chill\MainBundle\Search\SearchApiInterface;
use Chill\MainBundle\Search\SearchApiQuery;

class SearchUserApiProvider implements SearchApiInterface
{
    public function __construct(private readonly UserRepository $userRepository) {}

    public function getResult(string $key, array $metadata, float $pertinence)
    {
        return $this->userRepository->find($metadata['id']);
    }

    public function prepare(array $metadatas): void
    {
        $ids = \array_map(static fn ($m) => $m['id'], $metadatas);

        $this->userRepository->findBy(['id' => $ids]);
    }

    public function provideQuery(string $pattern, array $parameters): SearchApiQuery
    {
        $query = new SearchApiQuery();
        $query
            ->setSelectKey('user')
            ->setSelectJsonbMetadata("jsonb_build_object('id', u.id)")
            ->setSelectPertinence('3 + GREATEST(SIMILARITY(LOWER(UNACCENT(?)), u.label),
                SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical))', [$pattern, $pattern])
            ->setFromClause('users AS u')
            ->setWhereClauses('
                u.enabled IS TRUE and (
                SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical) > 0.15
                OR u.usernamecanonical LIKE \'%\' || LOWER(UNACCENT(?)) || \'%\'
                OR SIMILARITY(LOWER(UNACCENT(?)), LOWER(UNACCENT(u.label))) > 0.15
                OR u.label LIKE \'%\' || LOWER(UNACCENT(?)) || \'%\'
            )', [$pattern, $pattern, $pattern, $pattern]);

        return $query;
    }

    public function supportsResult(string $key, array $metadatas): bool
    {
        return 'user' === $key;
    }

    public function supportsTypes(string $pattern, array $types, array $parameters): bool
    {
        return \in_array('user', $types, true);
    }
}
