<?php

namespace App\Tests\Domain\Manga\Application\CommandHandler;

use App\Domain\Manga\Application\Command\FetchMangaChapters;
use App\Domain\Manga\Application\CommandHandler\FetchMangaChaptersHandler;
use App\Domain\Manga\Domain\Exception\MangadexApiException;
use App\Domain\Manga\Domain\Model\Manga;
use App\Domain\Manga\Domain\Model\ValueObject\ExternalId;
use App\Domain\Manga\Domain\Model\ValueObject\MangaId;
use App\Domain\Manga\Domain\Model\ValueObject\MangaSlug;
use App\Domain\Manga\Domain\Model\ValueObject\MangaTitle;
use App\Tests\Domain\Manga\Adapter\InMemoryChapterSynchronizationService;
use App\Tests\Domain\Manga\Adapter\InMemoryMangaRepository;
use PHPUnit\Framework\TestCase;

class FetchMangaChaptersHandlerTest extends TestCase
{
    private InMemoryChapterSynchronizationService $chapterSynchronizationService;
    private InMemoryMangaRepository $mangaRepository;
    private FetchMangaChaptersHandler $handler;

    protected function setUp(): void
    {
        $this->chapterSynchronizationService = new InMemoryChapterSynchronizationService();
        $this->mangaRepository = new InMemoryMangaRepository();
        $this->handler = new FetchMangaChaptersHandler(
            $this->mangaRepository,
            $this->chapterSynchronizationService
        );
    }

    public function testHandleWithExistingManga(): void
    {
        $mangaId = 'manga-id';
        $externalId = 'manga-123';
        $manga = new Manga(
            new MangaId($mangaId),
            new MangaTitle('Test Manga'),
            new MangaSlug('test-manga'),
            'Description',
            'Author',
            2024,
            [],
            'ongoing',
            new ExternalId($externalId)
        );

        $this->mangaRepository->save($manga);

        $command = new FetchMangaChapters(new MangaId($mangaId));
        $this->handler->handle($command);

        $synchronizedChapters = $this->chapterSynchronizationService->getSynchronizedChapters();
        $this->assertCount(1, $synchronizedChapters);
        $this->assertArrayHasKey($mangaId, $synchronizedChapters);
    }

    public function testHandleWithNonExistingManga(): void
    {
        $mangaId = 'non-existing-manga';

        $this->expectException(\RuntimeException::class);
        $this->expectExceptionMessage('Manga not found');

        $command = new FetchMangaChapters(new MangaId($mangaId));
        $this->handler->handle($command);
    }

    public function testHandleWithMangaWithoutExternalId(): void
    {
        $mangaId = 'manga-id';
        $manga = new Manga(
            new MangaId($mangaId),
            new MangaTitle('Test Manga'),
            new MangaSlug('test-manga'),
            'Description',
            'Author',
            2024,
            [],
            'ongoing',
            null // Pas d'externalId
        );

        $this->mangaRepository->save($manga);

        $this->expectException(MangadexApiException::class);
        $this->expectExceptionMessage('Manga has no external_id');

        $command = new FetchMangaChapters(new MangaId($mangaId));
        $this->handler->handle($command);
    }
}
