<?php

namespace App\Domain\Manga\Application\QueryHandler;

use App\Domain\Manga\Application\Query\DiscoverManga;
use App\Domain\Manga\Application\Response\MangaSearchItem;
use App\Domain\Manga\Application\Response\MangaSearchResponse;
use App\Domain\Manga\Domain\Contract\Provider\MangaProviderInterface;
use App\Domain\Manga\Domain\Contract\Repository\MangaRepositoryInterface;
use App\Domain\Manga\Domain\Model\Manga;

readonly class DiscoverMangaHandler
{
    public function __construct(
        private MangaRepositoryInterface $mangaRepository,
        private MangaProviderInterface $mangaProvider
    ) {
    }

    public function handle(DiscoverManga $query): MangaSearchResponse
    {
        $localMangas = $this->mangaRepository->findAll(page: 1, limit: 1000);

        $ownedExternalIds = [];
        $mangasWithRating = [];
        foreach ($localMangas as $manga) {
            if (!$manga->getExternalId()) {
                continue;
            }
            $ownedExternalIds[] = $manga->getExternalId()->getValue();
            $mangasWithRating[] = $manga;
        }

        usort($mangasWithRating, fn ($a, $b) => ($b->getRating() ?? 0) <=> ($a->getRating() ?? 0));
        $sourceIds = array_map(
            fn (Manga $m) => $m->getExternalId()->getValue(),
            array_slice($mangasWithRating, 0, 5)
        );

        $collection = $this->mangaProvider->discover($sourceIds);

        $recommendations = array_values(array_filter(
            $collection->getItems(),
            fn (Manga $m) => $m->getExternalId() === null
                || !in_array($m->getExternalId()->getValue(), $ownedExternalIds, true)
        ));

        return new MangaSearchResponse(
            array_map(
                fn (Manga $manga, int $index) => new MangaSearchItem(
                    id: $index,
                    externalId: $manga->getExternalId()->getValue(),
                    title: $manga->getTitle()->getValue(),
                    slug: $manga->getSlug()->getValue(),
                    description: $manga->getDescription(),
                    author: $manga->getAuthor(),
                    publicationYear: $manga->getPublicationYear(),
                    genres: $manga->getGenres(),
                    status: $manga->getStatus(),
                    imageUrl: $manga->getImageUrl(),
                    thumbnailUrl: $manga->getImageUrls()?->getThumbnail(),
                    rating: $manga->getRating()
                ),
                $recommendations,
                array_keys($recommendations)
            )
        );
    }
}
