<?php

declare(strict_types=1);

namespace App\Tests\Functional\Administration\Api;

use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use PHPUnit\Framework\Attributes\Test;

/**
 * [P0] Functional tests for the refresh token endpoint.
 *
 * Verifies:
 * - Endpoint accessibility
 * - Missing token handling (401)
 * - Invalid token handling
 * - Cookie-based authentication
 */
final class RefreshTokenEndpointTest extends ApiTestCase
{
    protected static ?bool $alwaysBootKernel = true;

    #[Test]
    public function refreshEndpointReturns401WithoutCookie(): void
    {
        // GIVEN: No refresh_token cookie
        $client = static::createClient();

        // WHEN: Calling refresh endpoint
        $response = $client->request('POST', '/api/token/refresh', [
            'json' => [],
            'headers' => [
                'Host' => 'localhost',
            ],
        ]);

        // THEN: Returns 401 Unauthorized
        self::assertResponseStatusCodeSame(401);
    }

    #[Test]
    public function logoutEndpointIsAccessibleWithoutToken(): void
    {
        // GIVEN: No authentication
        $client = static::createClient();

        // WHEN: Calling logout endpoint
        $response = $client->request('POST', '/api/token/logout', [
            'json' => [],
            'headers' => [
                'Host' => 'localhost',
            ],
        ]);

        // THEN: Returns 200 OK (idempotent - no token to invalidate)
        self::assertResponseIsSuccessful();
    }

    #[Test]
    public function logoutEndpointClearsCookies(): void
    {
        // GIVEN: A client
        $client = static::createClient();

        // WHEN: Calling logout
        $response = $client->request('POST', '/api/token/logout', [
            'headers' => [
                'Host' => 'localhost',
                'Cookie' => 'refresh_token=some-token-value',
            ],
        ]);

        // THEN: Response sets expired cookies
        $setCookieHeaders = $response->getHeaders(false)['set-cookie'] ?? [];
        $this->assertNotEmpty($setCookieHeaders);

        $hasClearedCookie = false;
        foreach ($setCookieHeaders as $cookie) {
            if (str_contains($cookie, 'refresh_token=') && str_contains($cookie, 'expires=')) {
                $hasClearedCookie = true;
                break;
            }
        }
        $this->assertTrue($hasClearedCookie, 'Should set expired refresh_token cookie');
    }

    #[Test]
    public function refreshEndpointWithInvalidTokenReturns401(): void
    {
        // GIVEN: An invalid/malformed token in cookie
        $client = static::createClient();

        // WHEN: Calling refresh with invalid cookie
        $response = $client->request('POST', '/api/token/refresh', [
            'json' => [],
            'headers' => [
                'Host' => 'localhost',
                'Cookie' => 'refresh_token=invalid-token-format',
            ],
        ]);

        // THEN: Returns 401 Unauthorized
        self::assertResponseStatusCodeSame(401);
    }
}
