<?php

namespace App\Tests\Feature\Manga;

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\Feature\AbstractApiTestCase;
use Zenstruck\Foundry\Test\ResetDatabase;

class ToggleMonitoringTest extends AbstractApiTestCase
{
    use ResetDatabase;

    public function testEnableMonitoringForExistingManga(): void
    {
        // Arrange
        $externalId = 'external-123';
        $manga = new Manga(
            new MangaId('temp-id'), // ID temporaire, sera remplacé par l'auto-généré
            new MangaTitle('Test Manga'),
            new MangaSlug('test-manga'),
            'Description',
            'Author',
            2024,
            [],
            'ongoing',
            new ExternalId($externalId)
        );

        $entity = $this->toEntity($manga);
        $this->entityManager->persist($entity);
        $this->entityManager->flush();

        $mangaId = $entity->getId(); // Récupère l'ID auto-généré

        // Act
        static::createClient()->request('POST', "/api/manga/{$mangaId}/monitoring/toggle", [
            'json' => [
                'enabled' => true
            ]
        ]);

        // Assert
        $this->assertResponseStatusCodeSame(204);

        // Vérifier que le statut de monitoring a été mis à jour dans la base de données
        $updatedEntity = $this->entityManager->find(\App\Entity\Manga::class, $mangaId);
        $this->assertNotNull($updatedEntity);
        $this->assertTrue($updatedEntity->isMonitored(), 'Le manga devrait être monitoré');
    }

    public function testDisableMonitoringForExistingManga(): void
    {
        // Arrange
        $externalId = 'external-123';
        $manga = new Manga(
            new MangaId('temp-id'), // ID temporaire, sera remplacé par l'auto-généré
            new MangaTitle('Test Manga'),
            new MangaSlug('test-manga'),
            'Description',
            'Author',
            2024,
            [],
            'ongoing',
            new ExternalId($externalId)
        );

        $entity = $this->toEntity($manga);
        $entity->setMonitored(true); // Initialiser à true pour tester la désactivation
        $this->entityManager->persist($entity);
        $this->entityManager->flush();

        $mangaId = $entity->getId(); // Récupère l'ID auto-généré

        // Act
        static::createClient()->request('POST', "/api/manga/{$mangaId}/monitoring/toggle", [
            'json' => [
                'enabled' => false
            ]
        ]);

        // Assert
        $this->assertResponseStatusCodeSame(204);

        // Vérifier que le statut de monitoring a été mis à jour dans la base de données
        $updatedEntity = $this->entityManager->find(\App\Entity\Manga::class, $mangaId);
        $this->assertNotNull($updatedEntity);
        $this->assertFalse($updatedEntity->isMonitored(), 'Le manga ne devrait plus être monitoré');
    }

    public function testToggleMonitoringWithNonExistingManga(): void
    {
        // Act & Assert
        static::createClient()->request('POST', '/api/manga/99999/monitoring/toggle', [
            'json' => [
                'enabled' => true
            ]
        ]);

        $this->assertResponseStatusCodeSame(404);
    }

    public function testToggleMonitoringWithMissingEnabledField(): void
    {
        // Arrange
        $externalId = 'external-123';
        $manga = new Manga(
            new MangaId('temp-id'), // ID temporaire, sera remplacé par l'auto-généré
            new MangaTitle('Test Manga'),
            new MangaSlug('test-manga'),
            'Description',
            'Author',
            2024,
            [],
            'ongoing',
            new ExternalId($externalId)
        );

        $entity = $this->toEntity($manga);
        $this->entityManager->persist($entity);
        $this->entityManager->flush();

        $mangaId = $entity->getId(); // Récupère l'ID auto-généré

        // Act & Assert
        static::createClient()->request('POST', "/api/manga/{$mangaId}/monitoring/toggle", [
            'json' => []
        ]);

        $this->assertResponseStatusCodeSame(422);
        $this->assertJsonContains([
            'violations' => [
                [
                    'propertyPath' => 'enabled',
                    'message' => 'Le champ enabled est obligatoire'
                ]
            ]
        ]);
    }

    public function testToggleMonitoringWithInvalidEnabledValue(): void
    {
        // Arrange
        $externalId = 'external-123';
        $manga = new Manga(
            new MangaId('temp-id'), // ID temporaire, sera remplacé par l'auto-généré
            new MangaTitle('Test Manga'),
            new MangaSlug('test-manga'),
            'Description',
            'Author',
            2024,
            [],
            'ongoing',
            new ExternalId($externalId)
        );

        $entity = $this->toEntity($manga);
        $this->entityManager->persist($entity);
        $this->entityManager->flush();

        $mangaId = $entity->getId(); // Récupère l'ID auto-généré

        // Act & Assert
        static::createClient()->request('POST', "/api/manga/{$mangaId}/monitoring/toggle", [
            'json' => [
                'enabled' => 'invalid'
            ]
        ]);

        $this->assertResponseStatusCodeSame(422);
        $this->assertJsonContains([
            'violations' => [
                [
                    'propertyPath' => 'enabled',
                    'message' => 'Cette valeur doit être de type bool.'
                ]
            ]
        ]);
    }

    private function toEntity(Manga $manga): \App\Entity\Manga
    {
        $entity = new \App\Entity\Manga();
        $entity->setTitle($manga->getTitle()->getValue())
            ->setSlug($manga->getSlug()->getValue())
            ->setDescription($manga->getDescription())
            ->setAuthor($manga->getAuthor())
            ->setPublicationYear($manga->getPublicationYear())
            ->setGenres($manga->getGenres())
            ->setStatus($manga->getStatus())
            ->setExternalId($manga->getExternalId()->getValue())
            ->setMonitored(false);

        return $entity;
    }
}
