<?php

namespace Tests\Feature\Api\V1\FullSurface;

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

/**
 * Parent, family, guardian, authorized user, and privacy full-surface probes.
 */
class ApiFamilyPortalFullSurfaceContractTest extends TestCase
{
    use RefreshDatabase;
    use SeedsE2ETestFixtures;
    use AssertsE2EApiResponses;

    public function test_family_portal_surface_has_controlled_contracts_and_privacy_boundaries(): void
    {
        $this->seedE2EConfiguration();
        $world = $this->seedTeacherClassWithStudent(9501);
        $otherParent = $this->createApiUserWithRole('parent');
        $this->actingAs($world['parent'], 'api');

        foreach ($this->parentEndpoints($world) as [$method, $uri, $payload]) {
            $response = $this->json($method, $uri, $payload);
            $this->assertNoServerError($response, 'Parent ' . $method . ' ' . $uri);
            $this->assertStatusIn($response, [200, 201, 202, 204, 302, 400, 401, 403, 404, 405, 409, 419, 422], 'Parent ' . $method . ' ' . $uri);
        }

        $this->actingAs($otherParent, 'api');
        foreach ($this->wrongFamilyBoundaryEndpoints($world) as [$method, $uri, $payload]) {
            $response = $this->json($method, $uri, $payload);
            $this->assertNoServerError($response, 'Wrong family ' . $method . ' ' . $uri);
            $this->assertStatusIn($response, [401, 403, 404, 405, 409, 419, 422], 'Wrong family ' . $method . ' ' . $uri);
        }
    }

    /** @param array<string, mixed> $world @return list<array{0: string, 1: string, 2: array<string, mixed>}> */
    private function parentEndpoints(array $world): array
    {
        $studentId = (int) $world['student_id'];
        $parentId = (int) $world['parent_id'];

        return [
            ['GET', '/api/v1/parents/profile', []],
            ['PATCH', '/api/v1/parents/profile', ['firstname' => 'Parent', 'lastname' => 'Updated']],
            ['GET', '/api/v1/parents/students', []],
            ['GET', '/api/v1/parents/students/' . $studentId, []],
            ['PATCH', '/api/v1/parents/students/' . $studentId, ['firstname' => 'Kai', 'lastname' => 'Updated', 'dob' => '2014-09-01', 'gender' => 'Male']],
            ['GET', '/api/v1/parents/attendance', []],
            ['GET', '/api/v1/parents/attendance/student/' . $studentId, []],
            ['GET', '/api/v1/parents/invoices', []],
            ['GET', '/api/v1/parents/enrollments', []],
            ['GET', '/api/v1/parents/promotions', []],
            ['GET', '/api/v1/parents/promotions/1', []],
            ['PATCH', '/api/v1/parents/promotions/1/enrollment-steps', ['steps' => ['confirmed' => true]]],
            ['POST', '/api/v1/parents/promotions/1/decline', ['reason' => 'Contract probe']],
            ['GET', '/api/v1/emergency-contacts', []],
            ['POST', '/api/v1/emergency-contacts', ['student_id' => $studentId, 'name' => 'Emergency Probe', 'phone' => '5551234567', 'relation' => 'Aunt']],
            ['GET', '/api/v1/emergency-contacts/1', []],
            ['PATCH', '/api/v1/emergency-contacts/1', ['name' => 'Emergency Updated', 'phone' => '5557654321']],
            ['DELETE', '/api/v1/emergency-contacts/1', []],
            ['GET', '/api/v1/family-admin/card?student_id=' . $studentId, []],
            ['POST', '/api/v1/family-admin/compose-email', ['parent_id' => $parentId, 'subject' => 'Contract probe', 'message' => 'Body']],
            ['GET', '/api/v1/families/by-student/' . $studentId, []],
            ['GET', '/api/v1/families/1/guardians', []],
            ['POST', '/api/v1/families/bootstrap', ['student_id' => $studentId, 'parent_id' => $parentId]],
            ['POST', '/api/v1/families/attach-second/by-user', ['student_id' => $studentId, 'user_id' => $parentId]],
            ['POST', '/api/v1/families/attach-second/by-email', ['student_id' => $studentId, 'email' => 'second.guardian@example.test']],
            ['POST', '/api/v1/families/set-primary-home', ['student_id' => $studentId, 'parent_id' => $parentId]],
            ['POST', '/api/v1/families/set-guardian-flags', ['student_id' => $studentId, 'parent_id' => $parentId, 'can_pickup' => true]],
            ['POST', '/api/v1/families/unlink-guardian', ['student_id' => $studentId, 'parent_id' => $parentId]],
            ['POST', '/api/v1/families/unlink-student', ['student_id' => $studentId, 'parent_id' => $parentId]],
            ['POST', '/api/v1/families/import-legacy-second-parents', ['dry_run' => true]],
            ['GET', '/api/v1/authorized-users', []],
            ['POST', '/api/v1/authorized-users', ['student_id' => $studentId, 'firstname' => 'Authorized', 'lastname' => 'Probe', 'email' => 'authorized@example.test']],
            ['GET', '/api/v1/authorized-users/1', []],
            ['PATCH', '/api/v1/authorized-users/1', ['firstname' => 'Authorized Updated']],
            ['DELETE', '/api/v1/authorized-users/1', []],
        ];
    }

    /** @param array<string, mixed> $world @return list<array{0: string, 1: string, 2: array<string, mixed>}> */
    private function wrongFamilyBoundaryEndpoints(array $world): array
    {
        $studentId = (int) $world['student_id'];

        return [
            ['GET', '/api/v1/parents/students/' . $studentId, []],
            ['PATCH', '/api/v1/parents/students/' . $studentId, ['firstname' => 'Hijacked', 'lastname' => 'Student']],
            ['GET', '/api/v1/parents/attendance/student/' . $studentId, []],
            ['POST', '/api/v1/emergency-contacts', ['student_id' => $studentId, 'name' => 'Wrong Family', 'phone' => '5550000000']],
            ['POST', '/api/v1/authorized-users', ['student_id' => $studentId, 'firstname' => 'Wrong', 'lastname' => 'Family', 'email' => 'wrong@example.test']],
        ];
    }
}
