<?php

namespace Tests\Feature\Api\V1\FullSurface;

use App\Models\User;
use Tests\Feature\Api\V1\FullSurface\Support\FullSurfaceE2EContractCase;

class ApiDeepAuthorizationIsolationMatrixTest extends FullSurfaceE2EContractCase
{
    public function test_role_isolation_matrix_blocks_cross_portal_access_for_sensitive_surfaces(): void
    {
        $failures = [];

        foreach ($this->isolationMatrix() as $label => [$actor, $method, $uri]) {
            $response = $this->requestAs($actor, $method, $uri, $this->payloadFor($method, ltrim($uri, '/')));
            $status = $response->getStatusCode();

            if (! in_array($status, [401, 403, 404, 405, 419, 422], true)) {
                $failures[] = "$label allowed cross-portal access with $status: " . $response->getContent();
            }
        }

        $this->assertSame([], $failures, "Cross-role authorization isolation failed:\n" . implode("\n", $failures));
    }

    public function test_owner_scoped_parent_routes_do_not_expose_another_family_student(): void
    {
        $otherWorld = $this->seedTeacherClassWithStudent(9702);
        $foreignStudentId = (int) $otherWorld['student_id'];

        $checks = [
            ['GET', "/api/v1/parents/students/$foreignStudentId"],
            ['PATCH', "/api/v1/parents/students/$foreignStudentId"],
            ['GET', "/api/v1/parents/students/$foreignStudentId/attendance"],
            ['GET', "/api/v1/parents/students/$foreignStudentId/invoices"],
            ['POST', "/api/v1/parents/students/$foreignStudentId/emergency-contacts"],
        ];

        $failures = [];
        foreach ($checks as [$method, $uri]) {
            $response = $this->requestAs($this->parent, $method, $uri, $this->payloadFor($method, ltrim($uri, '/')));
            $status = $response->getStatusCode();

            if (! in_array($status, [401, 403, 404, 405, 419, 422], true)) {
                $failures[] = "$method $uri leaked cross-family access with $status: " . $response->getContent();
            }
        }

        $this->assertSame([], $failures, "Parent owner-scope boundaries failed:\n" . implode("\n", $failures));
    }

    /** @return array<string, array{0: User, 1: string, 2: string}> */
    private function isolationMatrix(): array
    {
        return [
            'parent cannot see admin metrics' => [$this->parent, 'GET', '/api/v1/administrator/dashboard/metrics'],
            'parent cannot manage school years' => [$this->parent, 'POST', '/api/v1/school-years'],
            'parent cannot close school year' => [$this->parent, 'POST', '/api/v1/school-years/{schoolYear}/close'],
            'parent cannot view finance report' => [$this->parent, 'GET', '/api/v1/finance/financial-report'],
            'parent cannot manage inventory' => [$this->parent, 'POST', '/api/v1/inventory/items'],
            'teacher cannot manage users' => [$this->teacher, 'POST', '/api/v1/users'],
            'teacher cannot manage role permissions' => [$this->teacher, 'POST', '/api/v1/roles/{roleId}/permissions'],
            'teacher cannot close school year' => [$this->teacher, 'POST', '/api/v1/school-years/{schoolYear}/close'],
            'student cannot access teacher classes' => [$this->studentUser, 'GET', '/api/v1/teachers/classes'],
            'student cannot access parent profile' => [$this->studentUser, 'GET', '/api/v1/parents/profile'],
            'student cannot access admin dashboard' => [$this->studentUser, 'GET', '/api/v1/administrator/dashboard/metrics'],
            'admin cannot mutate parent-scoped child profile as portal parent' => [$this->admin, 'PATCH', '/api/v1/parents/students/{studentId}'],
        ];
    }
}
