<?php

namespace Tests\Feature;

use App\Mail\CourseNudgeMail;
use App\Models\Course;
use App\Models\Enrollment;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Mail;
use Tests\TestCase;

class CourseNudgeTest extends TestCase
{
    use RefreshDatabase;

    private function enrol(array $attrs = [], ?int $daysAgo = 6): Enrollment
    {
        $user = User::factory()->create();
        $course = Course::create(['slug' => 'c-'.uniqid(), 'title' => 'Test Course', 'is_published' => true]);

        $enrollment = Enrollment::create(array_merge([
            'user_id' => $user->id,
            'course_id' => $course->id,
            'status' => 'active',
            'progress' => 20,
        ], $attrs));

        if ($daysAgo !== null) {
            $enrollment->created_at = now()->subDays($daysAgo);
            $enrollment->save();
        }

        return $enrollment;
    }

    public function test_stalled_learner_is_nudged_and_stamped(): void
    {
        Mail::fake();
        $enrollment = $this->enrol();

        $this->artisan('courses:nudge-stalled')->assertSuccessful();

        Mail::assertSent(CourseNudgeMail::class, 1);
        $enrollment->refresh();
        $this->assertSame(1, (int) $enrollment->nudge_count);
        $this->assertNotNull($enrollment->last_nudged_at);
    }

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

        $this->enrol(['status' => 'completed', 'progress' => 100]);       // finished
        $this->enrol([], daysAgo: 1);                                     // too fresh (1 day)
        $this->enrol(['nudge_count' => 3]);                               // already nudged 3x
        $recentlyNudged = $this->enrol();
        $recentlyNudged->forceFill(['last_nudged_at' => now()->subDays(2)])->save(); // nudged 2 days ago

        $this->artisan('courses:nudge-stalled')->assertSuccessful();

        Mail::assertNothingSent();
    }

    public function test_log_mailer_does_not_spend_a_nudge(): void
    {
        config(['mail.default' => 'log']);
        $enrollment = $this->enrol();

        $this->artisan('courses:nudge-stalled')->assertSuccessful();

        $this->assertSame(0, (int) $enrollment->refresh()->nudge_count);
    }
}
