<?php

namespace Tests\Feature\Api\V1\Admin;

use App\Models\ClassSection;
use App\Models\Configuration;
use App\Models\Enrollment;
use App\Models\Student;
use App\Models\StudentClass;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;

class AdministratorEnrollmentQueryApiTest extends TestCase
{
    use RefreshDatabase;

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

        // Seed config expected by AdministratorSharedService
        Configuration::unguard();
        Configuration::query()->create([
            'config_key' => 'school_year',
            'config_value' => '2025-2026',
        ]);
        Configuration::query()->create([
            'config_key' => 'semester',
            'config_value' => 'Fall',
        ]);
    }

    public function test_enrollment_withdrawal_endpoint_returns_students_classes_and_years(): void
    {
        $admin = User::factory()->create();

        Sanctum::actingAs($admin);

        $parentOne = User::factory()->create([
            'firstname' => 'Parent',
            'lastname' => 'One',
        ]);

        $parentTwo = User::factory()->create([
            'firstname' => 'Parent',
            'lastname' => 'Two',
        ]);

        $studentOne = Student::factory()->create([
            'id' => 1,
            'parent_id' => $parentOne->id,
            'firstname' => 'Ali',
            'lastname' => 'Ben',
            'is_new' => 1,
            'registration_date' => '2025-09-10 08:00:00',
        ]);

        $studentTwo = Student::factory()->create([
            'id' => 2,
            'parent_id' => $parentTwo->id,
            'firstname' => 'Sara',
            'lastname' => 'Ali',
            'is_new' => 0,
            'registration_date' => '2024-09-10 08:00:00',
        ]);

        ClassSection::unguard();
        ClassSection::query()->create([
            'class_section_id' => 10,
            'class_section_name' => 'Grade 5A',
            'class_id' => 5,
            'school_year' => '2025-2026',
            'semester' => 'Fall',
        ]);

        StudentClass::unguard();
        StudentClass::query()->create([
            'student_id' => $studentOne->id,
            'class_section_id' => 10,
            'school_year' => '2025-2026',
            'semester' => 'Fall',
        ]);

        Enrollment::unguard();
        Enrollment::query()->create([
            'student_id' => $studentOne->id,
            'parent_id' => $parentOne->id,
            'school_year' => '2025-2026',
            'semester' => 'Fall',
            'enrollment_status' => 'enrolled',
            'admission_status' => 'accepted',
            'is_withdrawn' => 0,
            'enrollment_date' => now()->toDateString(),
        ]);

        Enrollment::query()->create([
            'student_id' => $studentTwo->id,
            'parent_id' => $parentTwo->id,
            'school_year' => '2024-2025',
            'semester' => 'Fall',
            'enrollment_status' => 'withdrawn',
            'admission_status' => 'accepted',
            'is_withdrawn' => 1,
            'enrollment_date' => now()->subYear()->toDateString(),
        ]);

        $response = $this->getJson('/api/v1/administrator/enrollment-withdrawal?schoolYear=2025-2026');

        $response->assertOk()
            ->assertJson([
                'semester' => 'Fall',
                'school_year' => '2025-2026',
            ])
            ->assertJsonCount(2, 'students')
            ->assertJsonCount(1, 'classes');

        $students = collect($response->json('students'));

        $first = $students->firstWhere('student_id', 1);
        $second = $students->firstWhere('student_id', 2);

        $this->assertSame('Yes', $first['new_student']);
        $this->assertSame('Grade 5A', $first['class_section']);
        $this->assertSame('enrolled', $first['enrollment_status']);
        $this->assertSame('2025-09-10', $first['registration_date_order']);

        $this->assertSame('No', $second['new_student']);
        $this->assertSame('Yes', $second['removed_previous_year']);
    }

    public function test_new_students_endpoint_returns_transformed_rows(): void
    {
        $admin = User::factory()->create();

        Sanctum::actingAs($admin);

        $parent = User::factory()->create([
            'firstname' => 'Parent',
            'lastname' => 'House',
        ]);

        $studentOne = Student::factory()->create([
            'id' => 9,
            'parent_id' => $parent->id,
            'firstname' => 'Adam',
            'lastname' => 'Y',
            'is_new' => 1,
            'registration_date' => '2025-10-01 10:00:00',
        ]);

        $studentTwo = Student::factory()->create([
            'id' => 10,
            'parent_id' => $parent->id,
            'firstname' => 'Eve',
            'lastname' => 'Z',
            'is_new' => 0,
            'registration_date' => null,
        ]);

        ClassSection::unguard();
        ClassSection::query()->create([
            'class_section_id' => 20,
            'class_section_name' => 'Grade 1A',
            'class_id' => 1,
            'school_year' => '2025-2026',
            'semester' => 'Fall',
        ]);

        StudentClass::unguard();
        StudentClass::query()->create([
            'student_id' => $studentOne->id,
            'class_section_id' => 20,
            'school_year' => '2025-2026',
            'semester' => 'Fall',
        ]);

        Enrollment::unguard();
        Enrollment::query()->create([
            'student_id' => $studentOne->id,
            'parent_id' => $parent->id,
            'school_year' => '2025-2026',
            'semester' => 'Fall',
            'enrollment_status' => 'enrolled',
            'admission_status' => 'accepted',
            'is_withdrawn' => 0,
            'enrollment_date' => now()->toDateString(),
        ]);

        Enrollment::query()->create([
            'student_id' => $studentTwo->id,
            'parent_id' => $parent->id,
            'school_year' => '2025-2026',
            'semester' => 'Fall',
            'enrollment_status' => 'waitlist',
            'admission_status' => 'pending',
            'is_withdrawn' => 0,
            'enrollment_date' => now()->toDateString(),
        ]);

        $response = $this->getJson('/api/v1/administrator/enrollment-withdrawal/new-students');

        $response->assertOk()
            ->assertJson([
                'total_new' => 2,
            ])
            ->assertJsonCount(2, 'new_students');

        $students = collect($response->json('new_students'));

        $first = $students->firstWhere('id', 9);
        $second = $students->firstWhere('id', 10);

        $this->assertSame('Yes', $first['new_student']);
        $this->assertSame('Grade 1A', $first['class_section']);
        $this->assertSame('enrolled', $first['enrollment_status']);
        $this->assertSame('contact_9', $first['modalIdContact']);
        $this->assertSame('2025-10-01', $first['registration_date']);

        $this->assertSame('No', $second['new_student']);
        $this->assertSame('Class not Assigned', $second['class_section']);
        $this->assertSame('waitlist', $second['enrollment_status']);
    }
}
