<?php

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

use App\Domain\Manga\Application\Query\GetMangaBySlug;
use App\Domain\Manga\Application\QueryHandler\GetMangaBySlugHandler;
use App\Domain\Manga\Domain\Exception\MangaNotFoundException;
use App\Domain\Manga\Domain\Model\Manga;
use App\Domain\Manga\Domain\Model\ValueObject\ImageUrls;
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\InMemoryMangaRepository;
use PHPUnit\Framework\TestCase;

class GetMangaBySlugHandlerTest extends TestCase
{
    private InMemoryMangaRepository $repository;
    private GetMangaBySlugHandler $handler;

    protected function setUp(): void
    {
        $this->repository = new InMemoryMangaRepository();
        $this->handler = new GetMangaBySlugHandler($this->repository);
    }

    public function testHandleReturnsCorrectMangaResponse(): void
    {
        // Arrange
        $manga = new Manga(
            id: new MangaId('1'),
            title: new MangaTitle('One Piece'),
            slug: new MangaSlug('one-piece'),
            description: 'Description',
            author: 'Eiichiro Oda',
            publicationYear: 1997,
            genres: ['Action', 'Adventure'],
            status: 'ongoing',
            externalId: null,
            imageUrl: 'https://example.com/image.jpg',
            imageUrls: new ImageUrls('https://example.com/image.jpg', 'https://example.com/thumbnail.jpg'),
            
            rating: 4.5
        );
        $this->repository->save($manga);

        // Act
        $response = $this->handler->handle(new GetMangaBySlug('one-piece'));

        // Assert
        $this->assertEquals('1', $response->id);
        $this->assertEquals('One Piece', $response->title);
        $this->assertEquals('one-piece', $response->slug);
        $this->assertEquals('Description', $response->description);
        $this->assertEquals('Eiichiro Oda', $response->author);
        $this->assertEquals(1997, $response->publicationYear);
        $this->assertEquals(['Action', 'Adventure'], $response->genres);
        $this->assertEquals('ongoing', $response->status);
        $this->assertNull($response->externalId);
        $this->assertEquals('https://example.com/image.jpg', $response->imageUrl);
        $this->assertEquals(4.5, $response->rating);
    }

    public function testHandleThrowsExceptionWhenMangaNotFound(): void
    {
        // Assert
        $this->expectException(MangaNotFoundException::class);

        // Act
        $this->handler->handle(new GetMangaBySlug('non-existent-manga'));
    }

    protected function tearDown(): void
    {
        $this->repository->clear();
    }
}
