<?php

namespace Tests\Unit\Models;

use App\Enums\PublishStatusEnum;
use App\Models\RouteArticle;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class RouteArticleRetryTest extends TestCase
{
    use RefreshDatabase;

    public function test_recording_a_failure_stores_the_reason(): void
    {
        /** @var RouteArticle $routeArticle */
        $routeArticle = RouteArticle::factory()->approved()->create();

        $routeArticle->recordPublishFailed('couldnt_find_community');

        $routeArticle->refresh();

        $this->assertSame(PublishStatusEnum::ERROR, $routeArticle->publish_status);
        $this->assertSame('couldnt_find_community', $routeArticle->publish_error);
    }

    public function test_clearing_a_failure_makes_it_publishable_again(): void
    {
        /** @var RouteArticle $routeArticle */
        $routeArticle = RouteArticle::factory()->approved()->create();
        $routeArticle->recordPublishFailed('boom');

        $routeArticle->clearPublishFailure();

        $routeArticle->refresh();

        $this->assertSame(PublishStatusEnum::UNPUBLISHED, $routeArticle->publish_status);
        $this->assertNull($routeArticle->publish_error);
    }

    public function test_a_failed_article_is_not_due_for_publishing(): void
    {
        /** @var RouteArticle $routeArticle */
        $routeArticle = RouteArticle::factory()->approved()->create();
        $routeArticle->recordPublishFailed('boom');

        $this->assertFalse(
            RouteArticle::query()->dueForPublishing()->whereKey($routeArticle->getKey())->exists()
        );
    }

    public function test_clearing_the_failure_returns_it_to_the_publish_queue(): void
    {
        /** @var RouteArticle $routeArticle */
        $routeArticle = RouteArticle::factory()->approved()->create();
        $routeArticle->recordPublishFailed('boom');
        $routeArticle->clearPublishFailure();

        $this->assertTrue(
            RouteArticle::query()->dueForPublishing()->whereKey($routeArticle->getKey())->exists()
        );
    }

    public function test_the_failed_scope_returns_only_failed_articles(): void
    {
        /** @var RouteArticle $failed */
        $failed = RouteArticle::factory()->approved()->create();
        $failed->recordPublishFailed('boom');

        RouteArticle::factory()->approved()->create();

        $ids = RouteArticle::failed()->pluck('id')->all();

        $this->assertSame([$failed->id], $ids);
    }

    public function test_a_failure_does_not_change_the_approval_decision(): void
    {
        /** @var RouteArticle $routeArticle */
        $routeArticle = RouteArticle::factory()->approved()->create();
        $decidedAt = $routeArticle->decided_at;

        $routeArticle->recordPublishFailed('boom');

        $routeArticle->refresh();

        $this->assertTrue($routeArticle->isApproved());
        $this->assertEquals($decidedAt, $routeArticle->decided_at);
    }
}
