<?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 H: Security and Unauthorized Access.
 *
 * @see docs/alrahma_end_to_end_use_case_test_plan.md Scenario H
 */
class ScenarioHSecurityUnauthorizedAccessTest extends TestCase
{
    use RefreshDatabase;
    use SeedsE2ETestFixtures;

    public function test_cross_role_and_anonymous_access_is_blocked(): void
    {
        $this->seedE2EConfiguration();
        $world = $this->seedTeacherClassWithStudent();
        $parentA = $this->createApiUserWithRole('parent');
        $teacher = $world['teacher'];
        $otherSectionId = $this->seedClassSection(902, '8B', 8);
        $otherTeacher = $this->createApiUserWithRole('teacher');
        $this->seedTeacherClassAssignment($otherTeacher->id, $otherSectionId);

        // Parent cannot update another family's student.
        $this->actingAs($parentA, 'api');
        $this->patchJson('/api/v1/parents/students/' . $world['student_id'], [
            'firstname' => 'Blocked',
            'lastname' => 'Update',
            'dob' => '2014-01-01',
            'gender' => 'Male',
        ])->assertNotFound();

        // Teacher cannot submit attendance for a class they are not assigned to.
        $this->actingAs($teacher, 'api');
        $this->postJson('/api/v1/attendance/teacher/submit', [
            'class_section_id' => $otherSectionId,
            'date' => '2025-10-05',
            'attendance' => [
                ['student_id' => $world['student_id'], 'status' => 'present'],
            ],
            'teachers' => [
                (string) $teacher->id => ['status' => 'present'],
            ],
        ])->assertStatus(422);

        // Teacher cannot access admin-only dashboard routes.
        $this->getJson('/api/v1/administrator/dashboard/metrics')->assertForbidden();
        $this->getJson('/api/v1/print-requests/admin')->assertForbidden();

        // Suspended user cannot log in after valid credentials.
        $suspended = $this->createApiUserWithRole('parent', [
            'email' => 'suspended.user@example.test',
            'password' => Hash::make('secret123'),
            'is_suspended' => 1,
        ]);

        $this->postJson('/api/v1/auth/login', [
            'email' => $suspended->email,
            'password' => 'secret123',
        ])->assertStatus(403);

        // Anonymous requests are rejected before business logic.
        $this->actingAsGuest('api');
        $this->getJson('/api/v1/finance/invoices/management')->assertUnauthorized();
        $this->getJson('/api/v1/administrator/dashboard/metrics')->assertUnauthorized();
        $this->getJson('/api/v1/parents/profile')->assertUnauthorized();
    }
}
