<?php

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

use App\Domain\Manga\Application\Query\GetMangaById;
use App\Domain\Manga\Application\QueryHandler\GetMangaByIdHandler;
use App\Domain\Manga\Domain\Exception\MangaNotFoundException;
use App\Domain\Manga\Domain\Model\Manga;
use App\Domain\Manga\Domain\Model\ValueObject\ExternalId;
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 GetMangaByIdHandlerTest extends TestCase
{
    private InMemoryMangaRepository $repository;
    private GetMangaByIdHandler $handler;

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

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

        $query = new GetMangaById('non-existent-id');
        $this->handler->handle($query);
    }

    public function testHandleReturnsMangaResponse(): void
    {
        // Arrange
        $manga = new Manga(
            id: new MangaId('123'),
            title: new MangaTitle('One Piece'),
            slug: new MangaSlug('one-piece'),
            description: 'Description test',
            author: 'Eiichiro Oda',
            publicationYear: 1997,
            genres: ['action', 'adventure'],
            status: 'ongoing',
            externalId: new ExternalId('external-123'),
            imageUrl: 'http://example.com/image.jpg',
            rating: 4.5,
            imageUrls: new ImageUrls('http://example.com/image.jpg', 'http://example.com/thumbnail.jpg'),
            createdAt: new \DateTimeImmutable()
        );
        $this->repository->save($manga);

        // Act
        $query = new GetMangaById('123');
        $response = $this->handler->handle($query);

        // Assert
        $this->assertEquals('123', $response->id);
        $this->assertEquals('One Piece', $response->title);
        $this->assertEquals('one-piece', $response->slug);
        $this->assertEquals('Description test', $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->assertEquals('external-123', $response->externalId);
        $this->assertEquals('http://example.com/image.jpg', $response->imageUrl);
        $this->assertEquals(4.5, $response->rating);
    }

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