<?php

namespace Tests\Unit\Actions;

use App\Actions\SaveArticleAction;
use App\Models\Article;
use App\Models\Feed;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class SaveArticleActionTest extends TestCase
{
    use RefreshDatabase;

    private function action(): SaveArticleAction
    {
        return app(SaveArticleAction::class);
    }

    public function test_it_creates_an_article_that_does_not_exist(): void
    {
        $feed = Feed::factory()->create();
        $url = 'https://example.com/unique-article';

        $this->assertDatabaseMissing('articles', ['url' => $url]);

        $article = $this->action()->execute($url, $feed->id);

        $this->assertInstanceOf(Article::class, $article);
        $this->assertSame($url, $article->url);
        $this->assertSame($feed->id, $article->feed_id);
        $this->assertDatabaseHas('articles', ['url' => $url, 'feed_id' => $feed->id]);
    }

    public function test_it_returns_the_existing_article_instead_of_duplicating(): void
    {
        $feed = Feed::factory()->create();
        $existing = Article::factory()->create([
            'url' => 'https://example.com/existing-article',
            'feed_id' => $feed->id,
        ]);

        $article = $this->action()->execute($existing->url, $feed->id);

        $this->assertSame($existing->id, $article->id);
        $this->assertSame(1, Article::where('url', $existing->url)->count());
    }

    public function test_it_creates_an_article_without_a_feed(): void
    {
        $url = 'https://example.com/article-without-feed';

        $article = $this->action()->execute($url, null);

        $this->assertSame($url, $article->url);
        $this->assertNull($article->feed_id);
        $this->assertDatabaseHas('articles', ['url' => $url, 'feed_id' => null]);
    }

    public function test_it_derives_a_readable_fallback_title_from_the_url(): void
    {
        $article = $this->action()->execute('https://example.com/some-great_story.html');

        $this->assertSame('Some Great Story', $article->title);
    }

    public function test_it_falls_back_to_untitled_when_the_url_has_no_usable_path(): void
    {
        $article = $this->action()->execute('https://example.com/');

        $this->assertSame('Untitled Article', $article->title);
    }
}
