<?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\PersonBundle\Search;

use Chill\MainBundle\Search\SearchApiInterface;
use Chill\MainBundle\Search\SearchApiQuery;
use Chill\MainBundle\Search\Utils\ExtractDateFromPattern;
use Chill\MainBundle\Search\Utils\ExtractPhonenumberFromPattern;
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
use Chill\PersonBundle\Repository\PersonACLAwareRepositoryInterface;
use Chill\PersonBundle\Repository\PersonRepository;
use Symfony\Component\Security\Core\Security;

class SearchPersonApiProvider implements SearchApiInterface
{
    public function __construct(private readonly PersonRepository $personRepository, private readonly PersonACLAwareRepositoryInterface $personACLAwareRepository, private readonly Security $security, private readonly AuthorizationHelperInterface $authorizationHelper, private readonly ExtractDateFromPattern $extractDateFromPattern, private readonly ExtractPhonenumberFromPattern $extractPhonenumberFromPattern) {}

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

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

        $this->personRepository->findByIds($ids);
    }

    public function provideQuery(string $pattern, array $parameters): SearchApiQuery
    {
        $datesResult = $this->extractDateFromPattern->extractDates($pattern);
        $phoneResult = $this->extractPhonenumberFromPattern->extractPhonenumber($datesResult->getFilteredSubject());
        $filtered = $phoneResult->getFilteredSubject();

        return $this->personACLAwareRepository->buildAuthorizedQuery(
            $filtered,
            null,
            null,
            \count($datesResult->getFound()) > 0 ? $datesResult->getFound()[0] : null,
            null,
            null,
            null,
            null,
            \count($phoneResult->getFound()) > 0 ? $phoneResult->getFound()[0] : null
        )
            ->setSelectKey('person')
            ->setSelectJsonbMetadata("jsonb_build_object('id', person.id)");
    }

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

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