<?php

declare(strict_types=1);

namespace App\Module\Integration\Infrastructure\ApiPlatform\State;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Module\Integration\Domain\Exception\BookStackApiException;
use App\Module\Integration\Infrastructure\ApiPlatform\Resource\BookStackSearchResult;
use App\Module\Integration\Infrastructure\Service\BookStackApiService;
use App\Module\ProjectManagement\Domain\Repository\TaskRepositoryInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

final readonly class BookStackSearchResultProvider implements ProviderInterface
{
    public function __construct(
        private BookStackApiService $bookStackApiService,
        private TaskRepositoryInterface $taskRepository,
        private RequestStack $requestStack,
    ) {}

    public function provide(Operation $operation, array $uriVariables = [], array $context = []): array
    {
        $taskId = $uriVariables['taskId'] ?? 0;
        $task   = $this->taskRepository->findById((int) $taskId);

        if (null === $task || null === $task->getProject()) {
            return [];
        }

        $shelfId = $task->getProject()->getBookstackShelfId();
        if (null === $shelfId) {
            return [];
        }

        $request = $this->requestStack->getCurrentRequest();
        $query   = $request?->query->get('q', '') ?? '';

        if ('' === trim($query)) {
            return [];
        }

        try {
            $results = $this->bookStackApiService->searchInShelf($shelfId, $query);
        } catch (BookStackApiException $e) {
            throw new BadRequestHttpException($e->getMessage(), $e);
        }

        return array_map(static function (array $item): BookStackSearchResult {
            $dto       = new BookStackSearchResult();
            $dto->id   = $item['id'];
            $dto->type = $item['type'];
            $dto->name = $item['name'];
            $dto->url  = $item['url'];

            return $dto;
        }, $results);
    }
}
