<?php

namespace Tests\Feature\Enrollment;

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Modules\Enrollment\Models\Enrollment;
use Modules\Students\Models\Student;
use Modules\Academic\Models\Classroom;
use Modules\Academic\Models\AcademicYear;
use Modules\Academic\Models\Subject;
use Modules\Results\Models\Result;
use Modules\Academic\Models\ExamType;
use App\Models\User;

class EnrollmentViewTest extends TestCase
{
    use RefreshDatabase;

    private User $adminUser;
    private User $teacherUser;
    private User $studentUser;
    private AcademicYear $academicYear;
    private Classroom $classroom;
    private Student $student;
    private Enrollment $enrollment;

    protected function setUp(): void
    {
        parent::setUp();

        // Create users
        $this->adminUser = User::factory()->create(['role' => 'admin']);
        $this->teacherUser = User::factory()->create(['role' => 'teacher']);
        $this->studentUser = User::factory()->create(['role' => 'student']);

        // Create academic year
        $this->academicYear = AcademicYear::factory()->create([
            'name' => '2024-2025',
            'is_active' => true,
        ]);

        // Create classroom
        $this->classroom = Classroom::factory()->create([
            'academic_year_id' => $this->academicYear->id,
            'name' => 'Grade 10A',
            'capacity' => 30,
        ]);

        // Create student
        $this->student = Student::factory()->create([
            'user_id' => $this->studentUser->id,
            'student_id' => 'STU001',
        ]);

        // Create enrollment
        $this->enrollment = Enrollment::factory()->create([
            'student_id' => $this->student->id,
            'classroom_id' => $this->classroom->id,
            'academic_year_id' => $this->academicYear->id,
            'is_active' => true,
        ]);
    }

    /** @test */
    public function admin_can_view_enrollment_index_page()
    {
        $response = $this->actingAs($this->adminUser)
            ->get(route('enrollment.index'));

        $response->assertStatus(200);
        $response->assertInertia(fn ($page) =>
            $page->component('Enrollment/Index')
                ->has('enrollments.data')
                ->has('academicYears')
                ->has('classrooms')
                ->has('statistics')
        );
    }

    /** @test */
    public function admin_can_view_enrollment_show_page()
    {
        $response = $this->actingAs($this->adminUser)
            ->get(route('enrollment.show', $this->enrollment->id));

        $response->assertStatus(200);
        $response->assertInertia(fn ($page) =>
            $page->component('Enrollment/Show')
                ->has('enrollment')
                ->where('enrollment.id', $this->enrollment->id)
                ->has('enrollmentHistory')
                ->has('recentResults')
        );
    }

    /** @test */
    public function admin_can_view_enrollment_edit_page()
    {
        $response = $this->actingAs($this->adminUser)
            ->get(route('enrollment.edit', $this->enrollment->id));

        $response->assertStatus(200);
        $response->assertInertia(fn ($page) =>
            $page->component('Enrollment/Edit')
                ->has('enrollment')
                ->where('enrollment.id', $this->enrollment->id)
                ->has('academicYears')
                ->has('classrooms')
        );
    }

    /** @test */
    public function admin_can_view_enrollment_create_page()
    {
        $response = $this->actingAs($this->adminUser)
            ->get(route('enrollment.create'));

        $response->assertStatus(200);
        $response->assertInertia(fn ($page) =>
            $page->component('Enrollment/Create')
                ->has('academicYears')
                ->has('classrooms')
                ->has('students')
        );
    }

    /** @test */
    public function admin_can_view_bulk_enroll_page()
    {
        $response = $this->actingAs($this->adminUser)
            ->get(route('enrollment.bulk-enroll'));

        $response->assertStatus(200);
        $response->assertInertia(fn ($page) =>
            $page->component('Enrollment/BulkEnroll')
                ->has('academicYears')
                ->has('classrooms')
        );
    }

    /** @test */
    public function enrollment_show_page_displays_correct_data()
    {
        // Create additional data for testing
        $subject = Subject::factory()->create(['name' => 'Mathematics']);
        $examType = ExamType::factory()->create([
            'name' => 'Midterm',
            'academic_year_id' => $this->academicYear->id,
        ]);

        $result = Result::factory()->create([
            'student_id' => $this->student->id,
            'classroom_id' => $this->classroom->id,
            'academic_year_id' => $this->academicYear->id,
            'subject_id' => $subject->id,
            'exam_type_id' => $examType->id,
            'marks' => 85,
            'grade' => 'A',
        ]);

        $response = $this->actingAs($this->adminUser)
            ->get(route('enrollment.show', $this->enrollment->id));

        $response->assertStatus(200);
        $response->assertInertia(fn ($page) =>
            $page->component('Enrollment/Show')
                ->where('enrollment.student.first_name', $this->student->first_name)
                ->where('enrollment.classroom.name', $this->classroom->name)
                ->where('enrollment.academic_year.name', $this->academicYear->name)
                ->has('recentResults', 1)
        );
    }

    /** @test */
    public function enrollment_index_page_can_be_filtered()
    {
        // Create additional enrollment for filtering
        $anotherClassroom = Classroom::factory()->create([
            'academic_year_id' => $this->academicYear->id,
            'name' => 'Grade 11A',
        ]);

        $anotherStudent = Student::factory()->create();
        Enrollment::factory()->create([
            'student_id' => $anotherStudent->id,
            'classroom_id' => $anotherClassroom->id,
            'academic_year_id' => $this->academicYear->id,
        ]);

        // Test filtering by classroom
        $response = $this->actingAs($this->adminUser)
            ->get(route('enrollment.index', ['classroom_id' => $this->classroom->id]));

        $response->assertStatus(200);
        $response->assertInertia(fn ($page) =>
            $page->component('Enrollment/Index')
                ->has('enrollments.data', 1)
                ->where('filters.classroom_id', (string) $this->classroom->id)
        );
    }

    /** @test */
    public function enrollment_index_page_can_be_searched()
    {
        $response = $this->actingAs($this->adminUser)
            ->get(route('enrollment.index', ['search' => $this->studentUser->first_name]));

        $response->assertStatus(200);
        $response->assertInertia(fn ($page) =>
            $page->component('Enrollment/Index')
                ->has('enrollments.data', 1)
                ->where('filters.search', $this->studentUser->first_name)
        );
    }

    /** @test */
    public function teacher_can_view_enrollments_for_their_classrooms()
    {
        // Create teacher record
        $teacher = \Modules\Teachers\Models\Teacher::factory()->create([
            'user_id' => $this->teacherUser->id,
        ]);

        // Assign teacher to classroom via classroom_subjects pivot table
        $subject = Subject::factory()->create(['name' => 'Mathematics']);
        $this->classroom->subjects()->attach($subject->id, ['teacher_id' => $this->teacherUser->id]);

        $response = $this->actingAs($this->teacherUser)
            ->get(route('enrollment.index'));

        $response->assertStatus(200);
        $response->assertInertia(fn ($page) =>
            $page->component('Enrollment/Index')
                ->has('enrollments.data')
        );
    }

    /** @test */
    public function unauthorized_user_cannot_view_enrollment_pages()
    {
        $unauthorizedUser = User::factory()->create(['role' => 'guardian']);

        // Test index page
        $response = $this->actingAs($unauthorizedUser)
            ->get(route('enrollment.index'));
        $response->assertStatus(403);

        // Test show page
        $response = $this->actingAs($unauthorizedUser)
            ->get(route('enrollment.show', $this->enrollment->id));
        $response->assertStatus(403);

        // Test edit page
        $response = $this->actingAs($unauthorizedUser)
            ->get(route('enrollment.edit', $this->enrollment->id));
        $response->assertStatus(403);

        // Test create page
        $response = $this->actingAs($unauthorizedUser)
            ->get(route('enrollment.create'));
        $response->assertStatus(403);
    }

    /** @test */
    public function enrollment_statistics_are_calculated_correctly()
    {
        // Create additional enrollments for statistics
        $inactiveEnrollment = Enrollment::factory()->create([
            'student_id' => Student::factory()->create()->id,
            'classroom_id' => $this->classroom->id,
            'academic_year_id' => $this->academicYear->id,
            'is_active' => false,
        ]);

        $response = $this->actingAs($this->adminUser)
            ->get(route('enrollment.index'));

        $response->assertStatus(200);
        $response->assertInertia(fn ($page) =>
            $page->component('Enrollment/Index')
                ->where('statistics.total_enrollments', 2)
                ->where('statistics.active_enrollments', 1)
                ->where('statistics.inactive_enrollments', 1)
        );
    }

    /** @test */
    public function enrollment_show_page_loads_related_data()
    {
        $response = $this->actingAs($this->adminUser)
            ->get(route('enrollment.show', $this->enrollment->id));

        $response->assertStatus(200);
        $response->assertInertia(fn ($page) =>
            $page->component('Enrollment/Show')
                ->has('enrollment.student.user')
                ->has('enrollment.classroom')
                ->has('enrollment.academic_year')
                ->has('enrollmentHistory')
                ->has('recentResults')
        );
    }

    /** @test */
    public function enrollment_edit_page_loads_form_data()
    {
        $response = $this->actingAs($this->adminUser)
            ->get(route('enrollment.edit', $this->enrollment->id));

        $response->assertStatus(200);
        $response->assertInertia(fn ($page) =>
            $page->component('Enrollment/Edit')
                ->where('enrollment.id', $this->enrollment->id)
                ->where('enrollment.classroom_id', $this->classroom->id)
                ->where('enrollment.academic_year_id', $this->academicYear->id)
                ->has('academicYears')
                ->has('classrooms')
        );
    }
}
