<?php

namespace Tests\Feature\Api\V1\FullSurface;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\Concerns\AssertsE2EApiResponses;
use Tests\Concerns\SeedsE2ETestFixtures;
use Tests\TestCase;

/**
 * Public/auth complete contract layer.
 */
class ApiPublicAndAuthFullSurfaceContractTest extends TestCase
{
    use RefreshDatabase;
    use SeedsE2ETestFixtures;
    use AssertsE2EApiResponses;

    public function test_public_and_auth_surface_has_stable_contracts(): void
    {
        $this->seedE2EConfiguration();
        $admin = $this->createApiUserWithRole('administrator');

        foreach ($this->publicGetEndpoints() as $uri) {
            $response = $this->getJson($uri);
            $this->assertNoServerError($response, 'Public GET ' . $uri);
            $this->assertStatusIn($response, [200, 302, 400, 401, 403, 404, 419, 422], 'Public GET ' . $uri);
        }

        foreach ($this->publicPostEndpoints() as [$uri, $payload]) {
            $response = $this->postJson($uri, $payload);
            $this->assertNoServerError($response, 'Public POST ' . $uri);
            $this->assertStatusIn($response, [200, 201, 202, 302, 400, 401, 403, 404, 419, 422], 'Public POST ' . $uri);
        }

        $login = $this->postJson('/api/v1/auth/login', ['email' => $admin->email, 'password' => 'password']);
        $this->assertNoServerError($login, 'Versioned auth login');
        $this->assertStatusIn($login, [200, 401, 403, 422], 'Versioned auth login');

        $this->actingAs($admin, 'api');
        foreach (['/api/v1/auth/me', '/api/v1/frontend/me', '/api/v1/auth/logout'] as $uri) {
            $response = str_ends_with($uri, 'logout') ? $this->postJson($uri) : $this->getJson($uri);
            $this->assertNoServerError($response, 'Authenticated auth/frontend endpoint ' . $uri);
            $this->assertStatusIn($response, [200, 204, 401, 403, 419, 422], 'Authenticated auth/frontend endpoint ' . $uri);
        }
    }

    /**
     * @return list<string>
     */
    private function publicGetEndpoints(): array
    {
        return [
            '/api/documentation',
            '/api/documentation/swagger',
            '/api/docs/public',
            '/api/access_denied',
            '/api/certificates/verify/invalid-token',
            '/api/timeoff/notify/invalid-token',
            '/api/winners/competitions',
            '/api/winners/competitions/1',
            '/api/confirm_authorized_user?token=invalid-token',
            '/api/set_authorized_user_password/1',
            '/api/v1/auth/register/captcha',
            '/api/v1/policies/school',
            '/api/v1/policies/picture',
            '/api/v1/pages/privacy',
            '/api/v1/pages/terms',
            '/api/v1/pages/help',
            '/api/v1/frontend',
            '/api/v1/frontend/facility',
            '/api/v1/frontend/team',
            '/api/v1/frontend/call-to-action',
            '/api/v1/frontend/testimonial',
            '/api/v1/frontend/not-found',
            '/api/v1/health',
            '/api/v1/system/db-check',
        ];
    }

    /**
     * @return list<array{0: string, 1: array<string, mixed>}>
     */
    private function publicPostEndpoints(): array
    {
        return [
            ['/api/login', ['email' => 'missing@example.test', 'password' => 'wrong-password']],
            ['/api/register', ['firstname' => 'Public', 'lastname' => 'Probe', 'email' => 'public.probe@example.test']],
            ['/api/v1/login', ['email' => 'missing@example.test', 'password' => 'wrong-password']],
            ['/api/v1/register', ['firstname' => 'Public', 'lastname' => 'Probe', 'email' => 'public.probe.v1@example.test']],
            ['/api/v1/auth/login', ['email' => 'missing@example.test', 'password' => 'wrong-password']],
            ['/api/v1/auth/register', ['firstname' => 'Public', 'lastname' => 'Probe', 'email' => 'public.auth@example.test']],
            ['/api/v1/pages/contact', ['name' => 'Public Probe', 'email' => 'public@example.test', 'message' => 'Contract probe']],
            ['/api/v1/contact', ['name' => 'Public Probe', 'email' => 'public@example.test', 'message' => 'Contract probe']],
            ['/api/v1/badge_scan/scan', ['badge_code' => 'INVALID-BADGE']],
            ['/api/v1/scanner/process', ['scan' => 'INVALID-BADGE']],
            ['/api/set_authorized_user_password/1', ['password' => 'secret123', 'password_confirmation' => 'secret123', 'token' => 'invalid-token']],
        ];
    }
}
