<?php

declare(strict_types=1);

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

use App\Domain\Manga\Application\EventListener\ChapterScrapedEventListener;
use App\Domain\Manga\Domain\Model\Chapter;
use App\Domain\Manga\Domain\Model\Manga;
use App\Domain\Manga\Domain\Model\ValueObject\ChapterId;
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\Domain\Shared\Domain\Event\ChapterScraped;
use App\Tests\Domain\Manga\Adapter\InMemoryMangaRepository;
use PHPUnit\Framework\TestCase;

class ChapterScrapedListenerTest extends TestCase
{
    private InMemoryMangaRepository $mangaRepository;
    private ChapterScrapedEventListener $listener;

    protected function setUp(): void
    {
        $this->mangaRepository = new InMemoryMangaRepository();
        $this->listener = new ChapterScrapedEventListener($this->mangaRepository);
    }

    public function testItUpdatesPagesDirectoryOnChapter(): void
    {
        $mangaId = 'manga-1';
        $chapterId = '42';

        $chapter = new Chapter(
            id: new ChapterId($chapterId),
            mangaId: new MangaId($mangaId),
            number: 5.0,
            title: 'Chapter 5',
            volume: 1,
            isVisible: true,
        );

        $manga = new Manga(
            new MangaId($mangaId),
            new MangaTitle('Test Manga'),
            new MangaSlug('test-manga'),
            'Description',
            'Author',
            2020,
            [],
            'ongoing'
        );

        $this->mangaRepository->save($manga);
        // Add chapter via separate path (bypass aggregate to seed state)
        $manga->addChapter($chapter);
        $this->mangaRepository->save($manga);

        $event = new ChapterScraped(
            jobId: 'job-abc',
            chapterId: $chapterId,
            pagesDirectory: '/data/pages/' . $chapterId,
            pageCount: 25,
        );

        ($this->listener)($event);

        $updatedChapter = $this->mangaRepository->findChapterById($chapterId);
        $this->assertNotNull($updatedChapter);
        $this->assertEquals('/data/pages/' . $chapterId, $updatedChapter->getPagesDirectory());
        $this->assertEquals(25, $updatedChapter->getPageCount());
    }

    public function testItDoesNothingWhenChapterNotFound(): void
    {
        $event = new ChapterScraped(
            jobId: 'job-xyz',
            chapterId: 'non-existent-chapter',
            pagesDirectory: '/data/pages/non-existent-chapter',
            pageCount: 10,
        );

        // Should not throw
        ($this->listener)($event);

        $this->assertNull($this->mangaRepository->findChapterById('non-existent-chapter'));
    }
}
