<?php

declare(strict_types=1);

namespace App\Tests\Api\Entity;

use App\Tests\AbstractApiTestCase;

/**
 * @internal
 */
class SiteTest extends AbstractApiTestCase
{
    public function testGetCollection(): void
    {
        $this->createSite('Usine Nord');
        $this->createSite('Usine Sud');

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

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

    public function testGetItem(): void
    {
        $site = $this->createSite('Usine Nord', ['contactCity' => 'Lyon']);

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

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains([
            'name'        => 'Usine Nord',
            'contactCity' => 'Lyon',
        ]);
    }

    public function testPost(): void
    {
        $client = $this->createGestionnaireClient();
        $client->request('POST', '/api/sites', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => [
                'name'        => 'Usine Est',
                'contactName' => 'Jean Dupont',
                'contactCity' => 'Strasbourg',
            ],
        ]);

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

    public function testPut(): void
    {
        $site = $this->createSite('Usine Nord');

        $client = $this->createGestionnaireClient();
        $client->request('PUT', self::iri('sites', $site->getId()), [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => ['name' => 'Usine Nord Renommée'],
        ]);

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains(['name' => 'Usine Nord Renommée']);
    }

    public function testPatch(): void
    {
        $site = $this->createSite('Usine Nord');

        $client = $this->createGestionnaireClient();
        $client->request('PATCH', self::iri('sites', $site->getId()), [
            'headers' => ['Content-Type' => 'application/merge-patch+json'],
            'json'    => ['contactPhone' => '0612345678'],
        ]);

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains(['contactPhone' => '0612345678']);
    }

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

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

        $this->assertResponseStatusCodeSame(204);
    }

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

        $this->assertResponseStatusCodeSame(401);
    }

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

        $this->assertResponseStatusCodeSame(403);
    }

    public function testValidationNameRequired(): void
    {
        $client = $this->createGestionnaireClient();
        $client->request('POST', '/api/sites', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => ['contactCity' => 'Paris'],
        ]);

        $this->assertResponseStatusCodeSame(422);
    }
}
