<?php

declare(strict_types=1);

namespace App\Tests\Api\Entity;

use App\Tests\AbstractApiTestCase;

/**
 * @internal
 */
class ProfileTest extends AbstractApiTestCase
{
    public function testGetCollectionAsAdmin(): void
    {
        $this->createProfile(firstName: 'Alice', lastName: 'Dupont');

        $client = $this->createAdminClient();
        $client->request('GET', '/api/profiles');

        $this->assertResponseIsSuccessful();
        $this->assertJsonContainsHydraCollection();
    }

    public function testGetCollectionForbiddenForViewer(): void
    {
        $client = $this->createViewerClient();
        $client->request('GET', '/api/profiles');

        $this->assertResponseStatusCodeSame(403);
    }

    public function testGetItemForbiddenForViewer(): void
    {
        $profile = $this->createProfile(firstName: 'Alice', lastName: 'Dupont');

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

        $this->assertResponseStatusCodeSame(403);
    }

    public function testGetItemAsAdmin(): void
    {
        $profile = $this->createProfile(firstName: 'Alice', lastName: 'Dupont');

        $client = $this->createAdminClient();
        $client->request('GET', self::iri('profiles', $profile->getId()));

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains([
            'firstName' => 'Alice',
            'lastName'  => 'Dupont',
        ]);
    }

    public function testPostAsAdmin(): void
    {
        $client = $this->createAdminClient();
        $client->request('POST', '/api/profiles', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => [
                'firstName'     => 'Nouveau',
                'lastName'      => 'Profil',
                'email'         => 'new@test.local',
                'plainPassword' => 'secret123',
                'roles'         => ['ROLE_VIEWER'],
            ],
        ]);

        $this->assertResponseStatusCodeSame(201);
        $this->assertJsonContains([
            'firstName' => 'Nouveau',
            'lastName'  => 'Profil',
        ]);
    }

    public function testPostForbiddenForGestionnaire(): void
    {
        $client = $this->createGestionnaireClient();
        $client->request('POST', '/api/profiles', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => [
                'firstName' => 'Blocked',
                'lastName'  => 'User',
            ],
        ]);

        $this->assertResponseStatusCodeSame(403);
    }

    public function testPatchAsAdmin(): void
    {
        $profile = $this->createProfile(firstName: 'Alice', lastName: 'Dupont');

        $client = $this->createAdminClient();
        $client->request('PATCH', self::iri('profiles', $profile->getId()), [
            'headers' => ['Content-Type' => 'application/merge-patch+json'],
            'json'    => ['firstName' => 'Alice modifiée'],
        ]);

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains(['firstName' => 'Alice modifiée']);
    }

    public function testDeleteAsAdmin(): void
    {
        $profile = $this->createProfile(firstName: 'ToDelete', lastName: 'User');

        $client = $this->createAdminClient();
        $client->request('DELETE', self::iri('profiles', $profile->getId()));

        $this->assertResponseStatusCodeSame(204);
    }

    public function testUnauthenticatedAccess(): void
    {
        $profile = $this->createProfile();

        $client = $this->createUnauthenticatedClient();
        $client->request('GET', self::iri('profiles', $profile->getId()));

        $this->assertResponseStatusCodeSame(401);
    }
}
