<?php

namespace Tests\Feature\Jobs;

use App\Enums\NotificationSeverityEnum;
use App\Enums\NotificationTypeEnum;
use App\Jobs\CheckFeedStalenessJob;
use App\Models\Feed;
use App\Models\Notification;
use App\Models\Setting;
use App\Services\Notification\NotificationService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class CheckFeedStalenessJobTest extends TestCase
{
    use RefreshDatabase;

    public function test_stale_feed_creates_notification(): void
    {
        $feed = Feed::factory()->create([
            'is_active' => true,
            'last_fetched_at' => now()->subHours(50),
        ]);

        $this->dispatch();

        $this->assertDatabaseHas('notifications', [
            'type' => NotificationTypeEnum::FEED_STALE->value,
            'severity' => NotificationSeverityEnum::WARNING->value,
            'notifiable_type' => $feed->getMorphClass(),
            'notifiable_id' => $feed->id,
        ]);
    }

    public function test_fresh_feed_does_not_create_notification(): void
    {
        Feed::factory()->create([
            'is_active' => true,
            'last_fetched_at' => now()->subHours(10),
        ]);

        $this->dispatch();

        $this->assertDatabaseCount('notifications', 0);
    }

    public function test_inactive_feed_does_not_create_notification(): void
    {
        Feed::factory()->create([
            'is_active' => false,
            'last_fetched_at' => now()->subHours(100),
        ]);

        $this->dispatch();

        $this->assertDatabaseCount('notifications', 0);
    }

    public function test_does_not_create_duplicate_notification_when_unread_exists(): void
    {
        $feed = Feed::factory()->create([
            'is_active' => true,
            'last_fetched_at' => now()->subHours(50),
        ]);

        Notification::factory()
            ->type(NotificationTypeEnum::FEED_STALE)
            ->unread()
            ->create([
                'notifiable_type' => $feed->getMorphClass(),
                'notifiable_id' => $feed->id,
            ]);

        $this->dispatch();

        $this->assertDatabaseCount('notifications', 1);
    }

    public function test_creates_new_notification_when_previous_is_read(): void
    {
        $feed = Feed::factory()->create([
            'is_active' => true,
            'last_fetched_at' => now()->subHours(50),
        ]);

        Notification::factory()
            ->type(NotificationTypeEnum::FEED_STALE)
            ->read()
            ->create([
                'notifiable_type' => $feed->getMorphClass(),
                'notifiable_id' => $feed->id,
            ]);

        $this->dispatch();

        $this->assertDatabaseCount('notifications', 2);
    }

    public function test_threshold_zero_disables_check(): void
    {
        Setting::setFeedStalenessThreshold(0);

        Feed::factory()->create([
            'is_active' => true,
            'last_fetched_at' => now()->subHours(100),
        ]);

        $this->dispatch();

        $this->assertDatabaseCount('notifications', 0);
    }

    public function test_never_fetched_feed_creates_notification(): void
    {
        $feed = Feed::factory()->create([
            'is_active' => true,
            'last_fetched_at' => null,
        ]);

        $this->dispatch();

        $this->assertDatabaseHas('notifications', [
            'type' => NotificationTypeEnum::FEED_STALE->value,
            'notifiable_type' => $feed->getMorphClass(),
            'notifiable_id' => $feed->id,
        ]);
    }

    private function dispatch(): void
    {
        (new CheckFeedStalenessJob)->handle(app(NotificationService::class));
    }
}
