<?php

namespace Tests\Feature\Api\Administrator;

use App\Models\AttendanceDay;
use App\Models\Configuration;
use App\Models\ScoreComment;
use App\Models\SemesterScore;
use App\Models\TeacherSubmissionNotificationHistory;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;

class AdministratorTeacherSubmissionReportApiTest extends TestCase
{
    use RefreshDatabase;

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

        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_teacher_submission_report_endpoint_returns_rows_summary_and_history(): void
    {
        $admin = User::factory()->create(['id' => 900, 'firstname' => 'Admin', 'lastname' => 'One']);
        Sanctum::actingAs($admin);

        User::factory()->create([
            'id' => 100,
            'firstname' => 'Main',
            'lastname' => 'Teacher',
            'email' => 'main@test.com',
        ]);
        User::factory()->create([
            'id' => 101,
            'firstname' => 'TA',
            'lastname' => 'Teacher',
            'email' => 'ta@test.com',
        ]);

        DB::table('classSection')->insert([
            [
                'class_section_id' => 10,
                'class_section_name' => 'Grade 5A',
                'class_id' => 5,
                'semester' => 'Fall',
                'school_year' => '2025-2026',
            ],
        ]);

        DB::table('teacher_class')->insert([
            [
                'class_section_id' => 10,
                'teacher_id' => 100,
                'position' => 'main',
                'school_year' => '2025-2026',
                'semester' => 'Fall',
            ],
            [
                'class_section_id' => 10,
                'teacher_id' => 101,
                'position' => 'ta',
                'school_year' => '2025-2026',
                'semester' => 'Fall',
            ],
        ]);

        DB::table('student_class')->insert([
            [
                'student_id' => 1,
                'class_section_id' => 10,
                'school_year' => '2025-2026',
                'semester' => 'Fall',
            ],
            [
                'student_id' => 2,
                'class_section_id' => 10,
                'school_year' => '2025-2026',
                'semester' => 'Fall',
            ],
        ]);

        $schoolId = (string) Str::uuid();
        SemesterScore::unguard();
        SemesterScore::query()->create([
            'student_id' => 1,
            'class_section_id' => 10,
            'school_id' => $schoolId,
            'school_year' => '2025-2026',
            'semester' => 'Fall',
            'midterm_exam_score' => '88',
            'participation_score' => '10',
        ]);
        SemesterScore::query()->create([
            'student_id' => 2,
            'class_section_id' => 10,
            'school_id' => $schoolId,
            'school_year' => '2025-2026',
            'semester' => 'Fall',
            'midterm_exam_score' => null,
            'participation_score' => '9',
        ]);

        ScoreComment::unguard();
        ScoreComment::query()->create([
            'student_id' => 1,
            'class_section_id' => 10,
            'school_year' => '2025-2026',
            'semester' => 'Fall',
            'score_type' => 'midterm',
            'comment' => 'Good progress',
        ]);
        ScoreComment::query()->create([
            'student_id' => 1,
            'class_section_id' => 10,
            'school_year' => '2025-2026',
            'semester' => 'Fall',
            'score_type' => 'ptap',
            'comment' => 'Great effort',
        ]);

        AttendanceDay::unguard();
        AttendanceDay::query()->create([
            'class_section_id' => 10,
            'school_year' => '2025-2026',
            'semester' => 'Fall',
            'date' => now()->format('Y-m-d'),
            'status' => 'submitted',
        ]);

        TeacherSubmissionNotificationHistory::unguard();
        TeacherSubmissionNotificationHistory::query()->create([
            'teacher_id' => 100,
            'class_section_id' => 10,
            'admin_id' => 900,
            'notification_category' => 'teacher_submissions',
            'message' => 'Reminder sent',
            'status' => 'sent',
            'school_year' => '2025-2026',
            'semester' => 'Fall',
            'sent_at' => now(),
        ]);

        $response = $this->getJson('/api/v1/administrator/teacher-submissions');

        $response->assertOk()
            ->assertJson([
                'semester' => 'Fall',
                'schoolYear' => '2025-2026',
            ])
            ->assertJsonCount(1, 'rows');

        $row = $response->json('rows.0');

        $this->assertSame('Grade 5A', $row['class_section']);
        $this->assertSame(10, $row['class_section_id']);
        $this->assertCount(2, $row['teachers']);
        $this->assertSame('Main: Main Teacher', $row['teachers'][0]['label']);
        $this->assertSame('TA: TA Teacher', $row['teachers'][1]['label']);

        $this->assertSame('Missing', $row['midterm_score_status']['label']);
        $this->assertSame('1/2', $row['midterm_score_status']['detail']);
        $this->assertSame('Missing', $row['midterm_comment_status']['label']);
        $this->assertSame('1/2', $row['midterm_comment_status']['detail']);
        $this->assertSame('Submitted', $row['participation_status']['label']);
        $this->assertSame('2/2', $row['participation_status']['detail']);
        $this->assertSame('Missing', $row['ptap_comment_status']['label']);
        $this->assertSame('1/2', $row['ptap_comment_status']['detail']);
        $this->assertSame('Submitted', $row['attendance_status']['label']);

        $this->assertSame([
            'midterm scores',
            'midterm comments',
            'PTAP comments',
        ], $row['missing_items']);

        $summary = $response->json('summary');
        $this->assertSame(5, $summary['total_items']);
        $this->assertSame(3, $summary['missing_items']);
        $this->assertSame(2, $summary['submitted_items']);
        $this->assertSame(40, $summary['submission_percentage']);

        $history = $response->json('notificationHistory');
        $this->assertSame('Admin One', $history['10']['100'][0]['admin_name']);
    }

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

        User::factory()->create([
            'id' => 200,
            'firstname' => 'Solo',
            'lastname' => 'Teacher',
            'email' => 'solo@test.com',
        ]);

        DB::table('classSection')->insert([
            [
                'class_section_id' => 11,
                'class_section_name' => 'Grade 6A',
                'class_id' => 6,
                'semester' => 'Fall',
                'school_year' => '2025-2026',
            ],
        ]);

        DB::table('teacher_class')->insert([
            [
                'class_section_id' => 11,
                'teacher_id' => 200,
                'position' => 'main',
                'school_year' => '2025-2026',
                'semester' => 'Fall',
            ],
        ]);

        $response = $this->getJson('/api/v1/administrator/teacher-submissions');

        $response->assertOk()
            ->assertJsonCount(1, 'rows');

        $row = $response->json('rows.0');

        $this->assertSame('No students', $row['midterm_score_status']['label']);
        $this->assertSame('No students', $row['midterm_comment_status']['label']);
        $this->assertSame('No students', $row['participation_status']['label']);
        $this->assertSame('No students', $row['ptap_comment_status']['label']);
        $this->assertSame([], $row['missing_items']);
        $this->assertSame(0, $row['student_count']);
    }

    public function test_teacher_submission_report_limits_history_to_three_entries(): void
    {
        $admin = User::factory()->create(['id' => 901, 'firstname' => 'Admin', 'lastname' => 'Two']);
        Sanctum::actingAs($admin);

        User::factory()->create([
            'id' => 300,
            'firstname' => 'Hist',
            'lastname' => 'Teacher',
            'email' => 'hist@test.com',
        ]);

        DB::table('classSection')->insert([
            [
                'class_section_id' => 12,
                'class_section_name' => 'Grade 7A',
                'class_id' => 7,
                'semester' => 'Fall',
                'school_year' => '2025-2026',
            ],
        ]);

        DB::table('teacher_class')->insert([
            [
                'class_section_id' => 12,
                'teacher_id' => 300,
                'position' => 'main',
                'school_year' => '2025-2026',
                'semester' => 'Fall',
            ],
        ]);

        TeacherSubmissionNotificationHistory::unguard();
        for ($i = 0; $i < 4; $i++) {
            TeacherSubmissionNotificationHistory::query()->create([
                'teacher_id' => 300,
                'class_section_id' => 12,
                'admin_id' => 901,
                'notification_category' => 'teacher_submissions',
                'message' => 'Reminder ' . $i,
                'status' => 'sent',
                'school_year' => '2025-2026',
                'semester' => 'Fall',
                'sent_at' => now()->subMinutes($i),
            ]);
        }

        $response = $this->getJson('/api/v1/administrator/teacher-submissions');

        $response->assertOk();

        $history = $response->json('notificationHistory.12.300');
        $this->assertCount(3, $history);
    }
}
