<?php

namespace Tests\Feature\Api\V1\Workflows;

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

/**
 * Scenario X: Public pages, kiosk scanning, badge scan logs, and verification links.
 *
 * This covers public and semi-public surfaces. They look harmless until someone
 * lets them mutate attendance, leak records, or crash on malformed tokens.
 */
class ScenarioXPublicKioskScannerAndVerificationLifecycleTest extends TestCase
{
    use RefreshDatabase;
    use SeedsE2ETestFixtures;
    use AssertsE2EApiResponses;

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

        foreach ([
            '/api/v1/frontend',
            '/api/v1/frontend/facility',
            '/api/v1/frontend/team',
            '/api/v1/frontend/call-to-action',
            '/api/v1/frontend/testimonial',
            '/api/v1/pages/privacy',
            '/api/v1/pages/terms',
            '/api/v1/pages/help',
            '/api/v1/policies/school',
            '/api/v1/policies/picture',
            '/api/v1/health',
            '/api/v1/system/db-check',
            '/api/documentation/swagger.json',
            '/api/docs/public',
        ] as $endpoint) {
            $response = $this->getJson($endpoint);
            $this->assertNoServerError($response, 'Public endpoint ' . $endpoint);
        }
    }

    public function test_badge_scan_and_scanner_process_known_and_unknown_codes_safely(): void
    {
        $world = $this->seedTeacherClassWithStudent();
        $admin = $this->actingAsApiAdministrator();
        $studentId = $world['student_id'];
        $badgeCode = 'E2E-BADGE-' . random_int(1000, 9999);

        DB::table('students')->where('id', $studentId)->update([
            'badge_scan' => $badgeCode,
        ]);

        $knownScan = $this->postJson('/api/v1/badge_scan/scan', [
            'code' => $badgeCode,
            'scanner' => 'front-desk',
            'scanned_at' => '2025-10-05 09:00:00',
        ]);
        $this->assertNoServerError($knownScan, 'Known badge scan');

        $unknownScan = $this->postJson('/api/v1/badge_scan/scan', [
            'code' => 'UNKNOWN-' . random_int(1000, 9999),
            'scanner' => 'front-desk',
            'scanned_at' => '2025-10-05 09:05:00',
        ]);
        $this->assertNoServerError($unknownScan, 'Unknown badge scan');

        $scannerProcess = $this->postJson('/api/v1/scanner/process', [
            'payload' => $badgeCode,
            'source' => 'kiosk',
        ]);
        $this->assertNoServerError($scannerProcess, 'Scanner process');

        $this->actingAs($admin, 'api');
        $this->getJson('/api/v1/badge_scan/logs')
            ->assertSuccessful();
    }

    public function test_public_verification_and_invite_tokens_fail_closed_for_invalid_values(): void
    {
        $this->getJson('/api/certificates/verify/not-a-real-token')
            ->assertStatus(404);

        $this->assertStatusIn(
            $this->getJson('/api/timeoff/notify/not-a-real-token'),
            [200, 302, 404, 410, 422],
            'Invalid time-off notification token'
        );

        $this->assertStatusIn(
            $this->getJson('/api/confirm_authorized_user?token=not-a-real-token'),
            [200, 302, 404, 410, 422],
            'Invalid authorized-user confirmation token'
        );

        $this->assertStatusIn(
            $this->getJson('/api/set_authorized_user_password/999999?token=not-a-real-token'),
            [200, 302, 404, 410, 422],
            'Invalid authorized-user set-password token'
        );
    }
}
