<?php

namespace Tests\Unit\Jobs;

use App\Enums\ApprovalStatusEnum;
use App\Jobs\CleanupArticlesJob;
use App\Models\Article;
use App\Models\Feed;
use App\Models\Route;
use App\Models\RouteArticle;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class CleanupArticlesJobTest extends TestCase
{
    use RefreshDatabase;

    public function test_deletes_old_articles_with_no_route_articles(): void
    {
        $old = Article::factory()->for(Feed::factory())->create([
            'created_at' => now()->subDays(31),
        ]);
        $recent = Article::factory()->for(Feed::factory())->create([
            'created_at' => now()->subDays(10),
        ]);

        (new CleanupArticlesJob)->handle();

        $this->assertDatabaseMissing('articles', ['id' => $old->id]);
        $this->assertDatabaseHas('articles', ['id' => $recent->id]);
    }

    public function test_preserves_old_articles_with_pending_route_articles(): void
    {
        $route = Route::factory()->create();
        $article = Article::factory()->for($route->feed)->create([
            'created_at' => now()->subDays(31),
        ]);
        RouteArticle::factory()->for($article)->create([
            'feed_id' => $route->feed_id,
            'platform_channel_id' => $route->platform_channel_id,
            'approval_status' => ApprovalStatusEnum::PENDING,
        ]);

        (new CleanupArticlesJob)->handle();

        $this->assertDatabaseHas('articles', ['id' => $article->id]);
    }

    public function test_preserves_old_articles_with_approved_route_articles(): void
    {
        $route = Route::factory()->create();
        $article = Article::factory()->for($route->feed)->create([
            'created_at' => now()->subDays(31),
        ]);
        RouteArticle::factory()->for($article)->create([
            'feed_id' => $route->feed_id,
            'platform_channel_id' => $route->platform_channel_id,
            'approval_status' => ApprovalStatusEnum::APPROVED,
        ]);

        (new CleanupArticlesJob)->handle();

        $this->assertDatabaseHas('articles', ['id' => $article->id]);
    }

    public function test_deletes_old_articles_with_only_rejected_route_articles(): void
    {
        $route = Route::factory()->create();
        $article = Article::factory()->for($route->feed)->create([
            'created_at' => now()->subDays(31),
        ]);
        RouteArticle::factory()->for($article)->create([
            'feed_id' => $route->feed_id,
            'platform_channel_id' => $route->platform_channel_id,
            'approval_status' => ApprovalStatusEnum::REJECTED,
        ]);

        (new CleanupArticlesJob)->handle();

        $this->assertDatabaseMissing('articles', ['id' => $article->id]);
    }

    public function test_cascade_deletes_route_articles(): void
    {
        $route = Route::factory()->create();
        $article = Article::factory()->for($route->feed)->create([
            'created_at' => now()->subDays(31),
        ]);
        $routeArticle = RouteArticle::factory()->for($article)->create([
            'feed_id' => $route->feed_id,
            'platform_channel_id' => $route->platform_channel_id,
            'approval_status' => ApprovalStatusEnum::REJECTED,
        ]);

        (new CleanupArticlesJob)->handle();

        $this->assertDatabaseMissing('route_articles', ['id' => $routeArticle->id]);
    }

    public function test_preserves_article_at_exact_retention_boundary(): void
    {
        $this->freezeTime();

        $boundary = Article::factory()->for(Feed::factory())->create([
            'created_at' => now()->subDays(30),
        ]);

        (new CleanupArticlesJob)->handle();

        $this->assertDatabaseHas('articles', ['id' => $boundary->id]);
    }
}
