<?php

namespace GriffinForms\Includes\CommandPalette;

use GriffinForms\Traits\Singleton;

class SearchProviderRegistry
{
    use Singleton;

    /** @var SearchProviderInterface[] */
    private array $providers = [];

    public function register(SearchProviderInterface $provider): void
    {
        $this->providers[$provider->getProviderId()] = $provider;
    }

    /** @return SearchProviderInterface[] */
    public function getAll(): array
    {
        return array_values($this->providers);
    }

    /** @return SearchResultItem[] */
    public function query(string $query, int $form_id): array
    {
        $providers = $this->getAll();
        usort($providers, fn($a, $b) => $a->getPriority() <=> $b->getPriority());

        $results = [];
        foreach ($providers as $provider) {
            try {
                $items = $provider->query($query, $form_id);
            } catch (\Throwable $e) {
                continue;
            }
            foreach ($items as $item) {
                if ($item instanceof SearchResultItem) {
                    $results[] = $item;
                }
            }
        }

        usort($results, function ($a, $b) {
            if ($a->score !== $b->score) {
                return $b->score <=> $a->score;
            }
            return 0;
        });

        return $results;
    }

    /** @return SearchResultItem[] */
    public function getQuickItems(int $form_id): array
    {
        $providers = $this->getAll();
        usort($providers, fn($a, $b) => $a->getPriority() <=> $b->getPriority());

        $results = [];
        foreach ($providers as $provider) {
            try {
                $items = $provider->getQuickItems($form_id);
            } catch (\Throwable $e) {
                continue;
            }
            foreach ($items as $item) {
                if ($item instanceof SearchResultItem) {
                    $results[] = $item;
                }
            }
        }

        return $results;
    }
}
