<?php

declare(strict_types=1);

namespace App\Tests\Api\Entity;

use App\Tests\AbstractApiTestCase;

/**
 * @internal
 */
class ConstructeurTest extends AbstractApiTestCase
{
    public function testGetCollection(): void
    {
        $this->createConstructeur('Siemens');
        $this->createConstructeur('ABB');

        $client = $this->createViewerClient();
        $client->request('GET', '/api/constructeurs');

        $this->assertResponseIsSuccessful();
        $this->assertJsonContainsHydraCollection();
        $this->assertJsonContains(['totalItems' => 2]);
    }

    public function testGetItem(): void
    {
        $c = $this->createConstructeur('Siemens', 'contact@siemens.com', '+33123456789');

        $client = $this->createViewerClient();
        $client->request('GET', self::iri('constructeurs', $c->getId()));

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains([
            'name'       => 'Siemens',
            'email'      => 'contact@siemens.com',
            'telephones' => [['numero' => '+33123456789']],
        ]);
    }

    public function testPost(): void
    {
        $client = $this->createGestionnaireClient();
        $client->request('POST', '/api/constructeurs', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => [
                'name'  => 'Schneider',
                'email' => 'info@schneider.com',
            ],
        ]);

        $this->assertResponseStatusCodeSame(201);
        $this->assertJsonContains(['name' => 'Schneider']);
    }

    public function testPut(): void
    {
        $c = $this->createConstructeur('Siemens');

        $client = $this->createGestionnaireClient();
        $client->request('PUT', self::iri('constructeurs', $c->getId()), [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => [
                'name'  => 'Siemens AG',
                'email' => 'updated@siemens.com',
            ],
        ]);

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains(['name' => 'Siemens AG']);
    }

    public function testPatch(): void
    {
        $c = $this->createConstructeur('Siemens');

        $client = $this->createGestionnaireClient();
        $client->request('PATCH', self::iri('constructeurs', $c->getId()), [
            'headers' => ['Content-Type' => 'application/merge-patch+json'],
            'json'    => ['email' => 'updated@siemens.com'],
        ]);

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains(['email' => 'updated@siemens.com']);
    }

    public function testPatchCategories(): void
    {
        $c    = $this->createConstructeur('Siemens');
        $cat1 = $this->createConstructeurCategorie('Transporteur');
        $cat2 = $this->createConstructeurCategorie('Organisme de formation');

        $client = $this->createGestionnaireClient();
        $client->request('PATCH', self::iri('constructeurs', $c->getId()), [
            'headers' => ['Content-Type' => 'application/merge-patch+json'],
            'json'    => ['categories' => [
                self::iri('constructeur_categories', $cat1->getId()),
                self::iri('constructeur_categories', $cat2->getId()),
            ]],
        ]);

        $this->assertResponseIsSuccessful();
        $client->request('GET', self::iri('constructeurs', $c->getId()));
        $this->assertResponseIsSuccessful();
        $this->assertJsonContains(['categories' => [['name' => 'Transporteur'], ['name' => 'Organisme de formation']]]);
    }

    public function testDelete(): void
    {
        $c = $this->createConstructeur('ToDelete');

        $client = $this->createGestionnaireClient();
        $client->request('DELETE', self::iri('constructeurs', $c->getId()));

        $this->assertResponseStatusCodeSame(204);
    }

    public function testUnauthenticatedAccess(): void
    {
        $client = $this->createUnauthenticatedClient();
        $client->request('GET', '/api/constructeurs');

        $this->assertResponseStatusCodeSame(401);
    }

    public function testViewerCannotWrite(): void
    {
        $client = $this->createViewerClient();
        $client->request('POST', '/api/constructeurs', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => ['name' => 'Blocked'],
        ]);

        $this->assertResponseStatusCodeSame(403);
    }

    public function testUniqueNameConstraint(): void
    {
        $this->createConstructeur('Siemens');

        $client = $this->createGestionnaireClient();
        $client->request('POST', '/api/constructeurs', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => ['name' => 'Siemens'],
        ]);

        $this->assertResponseStatusCodeSame(422);
    }
}
