<?php

namespace Tests\Feature\Api\V1\Workflows;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
use Tests\Concerns\SeedsE2ETestFixtures;
use Tests\TestCase;

/**
 * Scenario I: Public access, authentication lifecycle, and basic system probes.
 *
 * This keeps the front door honest before the deeper school workflows run.
 */
class ScenarioIPublicAuthAndSystemUseCaseTest extends TestCase
{
    use RefreshDatabase;
    use SeedsE2ETestFixtures;

    public function test_guest_can_use_public_content_contact_and_health_endpoints_without_authentication(): void
    {
        $this->seedE2EConfiguration();

        $publicGetEndpoints = [
            '/api/v1/health',
            '/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/auth/register/captcha',
        ];

        foreach ($publicGetEndpoints as $endpoint) {
            $response = $this->getJson($endpoint);

            $this->assertLessThan(
                500,
                $response->getStatusCode(),
                "$endpoint returned a server error. Public routes do not get to explode just because nobody logged in."
            );
        }

        $this->postJson('/api/v1/contact', [])
            ->assertStatus(422)
            ->assertJsonValidationErrors(['name', 'email', 'subject', 'message']);

        $this->postJson('/api/v1/contact', [
            'name' => 'Public Visitor',
            'email' => 'visitor@example.test',
            'subject' => 'Program question',
            'message' => 'Please send details about Sunday school registration.',
        ])
            ->assertCreated()
            ->assertJsonPath('status', true)
            ->assertJsonStructure(['status', 'message', 'data' => ['contact']]);
    }

    public function test_user_can_login_read_current_profile_and_logout_through_api(): void
    {
        $user = $this->createApiUserWithRole('teacher', [
            'firstname' => 'E2E',
            'lastname' => 'Teacher',
            'email' => 'e2e.auth.teacher@example.test',
            'password' => Hash::make('secret123'),
        ]);

        $login = $this->postJson('/api/v1/auth/login', [
            'email' => strtoupper($user->email),
            'password' => 'secret123',
        ])
            ->assertOk()
            ->assertJsonPath('status', true)
            ->assertJsonStructure([
                'token',
                'access_token',
                'token_type',
                'expires_in',
                'user' => ['id', 'name', 'firstname', 'lastname', 'email', 'roles'],
            ]);

        $token = (string) $login->json('token');
        $this->assertNotSame('', $token);

        $this->withHeader('Authorization', 'Bearer ' . $token)
            ->getJson('/api/v1/auth/me')
            ->assertOk()
            ->assertJsonPath('status', true)
            ->assertJsonPath('data.email', 'e2e.auth.teacher@example.test');

        $this->withHeader('Authorization', 'Bearer ' . $token)
            ->postJson('/api/v1/auth/logout')
            ->assertOk()
            ->assertJsonPath('status', true);
    }

    public function test_invalid_inactive_and_suspended_login_paths_fail_safely(): void
    {
        $active = $this->createApiUserWithRole('parent', [
            'email' => 'active.parent@example.test',
            'password' => Hash::make('secret123'),
            'is_suspended' => 0,
        ]);

        $this->postJson('/api/v1/auth/login', [
            'email' => $active->email,
            'password' => 'wrong-password',
        ])
            ->assertUnauthorized()
            ->assertJsonPath('status', false);

        $suspended = $this->createApiUserWithRole('parent', [
            'email' => 'suspended.parent@example.test',
            'password' => Hash::make('secret123'),
            'is_suspended' => 1,
        ]);

        $this->postJson('/api/v1/auth/login', [
            'email' => $suspended->email,
            'password' => 'secret123',
        ])
            ->assertForbidden()
            ->assertJsonPath('status', false);
    }
}
