<?php

namespace Tests\Feature\Api\V1\FullSurface;

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

/**
 * Classroom, attendance, grading, and report-card full-surface probes.
 */
class ApiAcademicAttendanceFullSurfaceContractTest extends TestCase
{
    use RefreshDatabase;
    use SeedsE2ETestFixtures;
    use AssertsE2EApiResponses;

    public function test_academic_attendance_and_grading_surfaces_have_controlled_contracts(): void
    {
        $this->seedE2EConfiguration();
        $world = $this->seedTeacherClassWithStudent(9301);
        $this->actingAs($world['teacher'], 'api');

        foreach ($this->teacherGetEndpoints($world) as $uri) {
            $response = $this->getJson($uri);
            $this->assertNoServerError($response, 'Teacher GET ' . $uri);
            $this->assertStatusIn($response, [200, 204, 302, 400, 401, 403, 404, 405, 409, 419, 422], 'Teacher GET ' . $uri);
        }

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

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

    /** @param array<string, mixed> $world @return list<string> */
    private function teacherGetEndpoints(array $world): array
    {
        $classSectionId = (int) $world['class_section_id'];
        $studentId = (int) $world['student_id'];

        return [
            '/api/v1/teachers/classes?class_section_id=' . $classSectionId,
            '/api/v1/teacher/class-view?class_section_id=' . $classSectionId,
            '/api/v1/teacher/no-classes',
            '/api/v1/teacher/select-semester',
            '/api/v1/teacher/homework-list?class_section_id=' . $classSectionId,
            '/api/v1/teacher/add-homework?class_section_id=' . $classSectionId,
            '/api/v1/teacher/add-quiz?class_section_id=' . $classSectionId,
            '/api/v1/teacher/add-quiz-column-form?class_section_id=' . $classSectionId,
            '/api/v1/teacher/add-midterm-exam?class_section_id=' . $classSectionId,
            '/api/v1/teacher/add-final-exam?class_section_id=' . $classSectionId,
            '/api/v1/teacher/add-participation?class_section_id=' . $classSectionId,
            '/api/v1/teacher/add-project?class_section_id=' . $classSectionId,
            '/api/v1/teacher/teacher-assignment',
            '/api/v1/teacher/exam-drafts',
            '/api/v1/teacher/drafts',
            '/api/v1/teacher/inventory/books/distribute',
            '/api/v1/teacher/print-requests/context',
            '/api/v1/teacher/absence-vacation',
            '/api/v1/teacher/showupdate-attendance?class_section_id=' . $classSectionId,
            '/api/v1/teacher/showupdate_attendance?class_section_id=' . $classSectionId,
            '/api/v1/teacher/scores?class_section_id=' . $classSectionId,
            '/api/v1/teacher/calendar',
            '/api/v1/teacher/class-progress-submit?class_section_id=' . $classSectionId,
            '/api/v1/teacher/class-progress-history?class_section_id=' . $classSectionId,
            '/api/v1/teacher/class-progress-view?class_section_id=' . $classSectionId,
            '/api/v1/teacher/competition-scores',
            '/api/v1/attendance/teacher/grid?class_section_id=' . $classSectionId,
            '/api/v1/attendance/teacher/form?class_section_id=' . $classSectionId,
            '/api/v1/attendance/admin/daily?date=2025-10-05&class_section_id=' . $classSectionId,
            '/api/v1/attendance/staff/month?month=2025-10',
            '/api/v1/attendance/staff/admins',
            '/api/v1/attendance/late-slip-logs',
            '/api/v1/attendance/late-slip-logs/1',
            '/api/v1/attendance/early-dismissals',
            '/api/v1/attendance/early-dismissals/student-options',
            '/api/v1/attendance/management/dashboard',
            '/api/v1/attendance-tracking/pending-violations',
            '/api/v1/attendance-tracking/notified-violations',
            '/api/v1/attendance-tracking/student-case/' . $studentId,
            '/api/v1/attendance-tracking/compose',
            '/api/v1/attendance-tracking/parents-info',
            '/api/v1/attendance-comment-templates',
            '/api/v1/attendance-comment-templates/list-data',
            '/api/v1/attendance-comment-templates/1',
            '/api/v1/attendance-templates',
            '/api/v1/assignments',
            '/api/v1/assignments/class-assignment-data',
            '/api/v1/scores/overview?class_section_id=' . $classSectionId,
            '/api/v1/scores/homework?class_section_id=' . $classSectionId,
            '/api/v1/scores/quiz?class_section_id=' . $classSectionId,
            '/api/v1/scores/project?class_section_id=' . $classSectionId,
            '/api/v1/scores/midterm?class_section_id=' . $classSectionId,
            '/api/v1/scores/final?class_section_id=' . $classSectionId,
            '/api/v1/scores/participation?class_section_id=' . $classSectionId,
            '/api/v1/grading/homework-tracking?class_section_id=' . $classSectionId,
            '/api/v1/reports/report-cards/meta?class_section_id=' . $classSectionId,
        ];
    }

    /** @param array<string, mixed> $world @return list<array{0: string, 1: string, 2: array<string, mixed>}> */
    private function teacherMutationEndpoints(array $world): array
    {
        $studentId = (int) $world['student_id'];
        $classSectionId = (int) $world['class_section_id'];
        $scorePayload = ['class_section_id' => $classSectionId, 'student_id' => $studentId, 'score' => 95, 'points' => 10, 'column' => 'E2E Probe'];

        return [
            ['POST', '/api/v1/attendance/teacher/submit', ['class_section_id' => $classSectionId, 'attendance' => [$studentId => 'present'], 'date' => '2025-10-05']],
            ['POST', '/api/v1/attendance/admin/update', ['student_id' => $studentId, 'status' => 'present', 'date' => '2025-10-05']],
            ['POST', '/api/v1/attendance/admin/add-entry', ['student_id' => $studentId, 'status' => 'present', 'date' => '2025-10-05']],
            ['POST', '/api/v1/attendance/staff/admins/save', ['attendance' => []]],
            ['POST', '/api/v1/attendance/staff/cell', ['user_id' => $world['teacher']->id, 'date' => '2025-10-05', 'status' => 'present']],
            ['DELETE', '/api/v1/attendance/late-slip-logs/1', []],
            ['POST', '/api/v1/attendance/early-dismissals', ['student_id' => $studentId, 'reason' => 'Contract probe', 'dismissal_time' => '12:00']],
            ['POST', '/api/v1/attendance/early-dismissals/signature', ['student_id' => $studentId, 'signature' => 'data:image/png;base64,ZmFrZQ==']],
            ['POST', '/api/v1/attendance/management/scan', ['badge_code' => 'INVALID-BADGE']],
            ['POST', '/api/v1/attendance/management/manual-entry', ['student_id' => $studentId, 'status' => 'present']],
            ['POST', '/api/v1/attendance/management/exit-entry', ['student_id' => $studentId]],
            ['POST', '/api/v1/attendance/management/absent', ['student_id' => $studentId]],
            ['POST', '/api/v1/attendance/management/1/follow-up', ['notes' => 'Contract probe']],
            ['POST', '/api/v1/attendance/management/1/late-slip-reprint', ['reason' => 'Contract probe']],
            ['POST', '/api/v1/attendance-tracking/record', ['student_id' => $studentId, 'violation_type' => 'late', 'date' => '2025-10-05']],
            ['POST', '/api/v1/attendance-tracking/send-auto-emails', ['student_ids' => [$studentId]]],
            ['POST', '/api/v1/attendance-tracking/send-manual-email', ['student_id' => $studentId, 'message' => 'Contract probe']],
            ['POST', '/api/v1/attendance-tracking/save-notification-note', ['student_id' => $studentId, 'note' => 'Contract probe']],
            ['POST', '/api/v1/attendance-comment-templates', ['name' => 'Probe', 'comment' => 'Contract probe']],
            ['PUT', '/api/v1/attendance-comment-templates/1', ['name' => 'Probe Updated', 'comment' => 'Contract probe updated']],
            ['DELETE', '/api/v1/attendance-comment-templates/1', []],
            ['POST', '/api/v1/attendance-templates/save', ['name' => 'Probe', 'comment' => 'Contract probe']],
            ['POST', '/api/v1/attendance-templates/delete', ['id' => 1]],
            ['POST', '/api/v1/assignments', ['class_section_id' => $classSectionId, 'title' => 'Contract Assignment']],
            ['POST', '/api/v1/teacher/add-homework', $scorePayload],
            ['POST', '/api/v1/teacher/add-quiz', $scorePayload],
            ['POST', '/api/v1/teacher/add-quiz-column-form', ['class_section_id' => $classSectionId, 'name' => 'Probe Quiz']],
            ['POST', '/api/v1/teacher/add-midterm-exam', $scorePayload],
            ['POST', '/api/v1/teacher/add-final-exam', $scorePayload],
            ['POST', '/api/v1/teacher/add-participation', $scorePayload],
            ['POST', '/api/v1/teacher/add-project', $scorePayload],
            ['POST', '/api/v1/teacher/exam-drafts', ['class_section_id' => $classSectionId, 'title' => 'Contract Draft', 'content' => 'Draft body']],
            ['POST', '/api/v1/teacher/drafts', ['class_section_id' => $classSectionId, 'title' => 'Contract Draft', 'content' => 'Draft body']],
            ['POST', '/api/v1/teacher/inventory/books/distribute', ['student_id' => $studentId, 'item_id' => 1, 'quantity' => 1]],
            ['POST', '/api/v1/teacher/absence-vacation', ['date' => '2025-10-05', 'reason' => 'Contract probe']],
            ['POST', '/api/v1/teacher/class-progress-submit', ['class_section_id' => $classSectionId, 'student_id' => $studentId, 'progress' => 'Good']],
        ];
    }

    /** @param array<string, mixed> $world @return list<array{0: string, 1: string, 2: array<string, mixed>}> */
    private function adminAcademicEndpoints(array $world): array
    {
        return [
            ['GET', '/api/v1/reports/report-cards?student_id=' . $world['student_id'], []],
            ['GET', '/api/v1/reports/stickers?student_id=' . $world['student_id'], []],
            ['GET', '/api/v1/badges/form-options', []],
            ['POST', '/api/v1/print-requests', ['title' => 'Contract Probe', 'copies' => 1, 'needed_by' => '2025-10-12']],
            ['GET', '/api/v1/print-requests/admin', []],
            ['PATCH', '/api/v1/print-requests/1/status', ['status' => 'completed']],
            ['GET', '/api/v1/print-requests/teacher', []],
            ['PATCH', '/api/v1/print-requests/1', ['title' => 'Contract Probe Updated']],
            ['DELETE', '/api/v1/print-requests/1', []],
        ];
    }
}
