<?php

namespace Tests\Feature\Api\Administrator;

use App\Models\Configuration;
use App\Models\TeacherSubmissionNotificationHistory;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;

class AdministratorTeacherSubmissionNotifyApiTest 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_notify_endpoint_requires_notify_payload(): void
    {
        $admin = User::factory()->create();
        Sanctum::actingAs($admin);

        $response = $this->postJson('/api/v1/administrator/teacher-submissions/notify', [
            'missing_items' => [],
        ]);

        $response->assertStatus(422)
            ->assertJsonValidationErrors(['notify']);
    }

    public function test_notify_endpoint_sends_email_and_creates_history_row(): void
    {
        Mail::fake();

        $admin = User::factory()->create([
            'id' => 900,
            'firstname' => 'Admin',
            'lastname' => 'One',
            'email' => 'admin@test.com',
        ]);
        Sanctum::actingAs($admin);

        User::factory()->create([
            'id' => 100,
            'firstname' => 'John',
            'lastname' => 'Teacher',
            'email' => 'teacher@test.com',
        ]);

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

        $payload = [
            'notify' => [
                10 => [
                    100 => 1,
                ],
            ],
            'missing_items' => [
                10 => [
                    100 => base64_encode(json_encode([
                        'midterm scores',
                        'attendance',
                    ])),
                ],
            ],
        ];

        $response = $this->postJson('/api/v1/administrator/teacher-submissions/notify', $payload);

        $response->assertOk()
            ->assertJson([
                'sent' => 1,
                'failed' => 0,
            ]);

        Mail::assertSentCount(1);

        $this->assertDatabaseHas('teacher_submission_notification_history', [
            'teacher_id' => 100,
            'class_section_id' => 10,
            'admin_id' => 900,
            'notification_category' => 'teacher_submissions',
            'status' => 'sent',
            'school_year' => '2025-2026',
            'semester' => 'Fall',
        ]);

        $history = TeacherSubmissionNotificationHistory::query()->latest('id')->first();
        $this->assertNotNull($history);
        $this->assertStringContainsString('midterm scores and attendance', strtolower((string) $history->message));
    }

    public function test_notify_endpoint_marks_failed_when_teacher_email_is_invalid(): void
    {
        Mail::fake();

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

        User::factory()->create([
            'id' => 101,
            'firstname' => 'Bad',
            'lastname' => 'Email',
            'email' => 'not-an-email',
        ]);

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

        $payload = [
            'notify' => [
                11 => [
                    101 => 1,
                ],
            ],
        ];

        $response = $this->postJson('/api/v1/administrator/teacher-submissions/notify', $payload);

        $response->assertStatus(207)
            ->assertJson([
                'sent' => 0,
                'failed' => 1,
            ]);

        Mail::assertNothingSent();

        $this->assertDatabaseHas('teacher_submission_notification_history', [
            'teacher_id' => 101,
            'class_section_id' => 11,
            'admin_id' => 901,
            'notification_category' => 'teacher_submissions',
            'status' => 'failed',
            'school_year' => '2025-2026',
            'semester' => 'Fall',
        ]);
    }
}
