<?php

namespace Tests\Unit\Actions;

use App\Models\Feed;
use App\Models\Language;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Mockery;
use Tests\TestCase;
use Tests\Traits\CreatesFetchActions;

/**
 * Belga discovery runs through the website path against a JSON API rather than
 * a rendered homepage. This lives in its own file because ArticleFetcherTest
 * registers a catch-all Http::fake in setUp() that a per-test fake cannot
 * override.
 */
class FetchWebsiteArticlesBelgaTest extends TestCase
{
    use CreatesFetchActions, RefreshDatabase;

    private function apiResponse(): string
    {
        $contents = file_get_contents(__DIR__.'/../../Fixtures/belga-pressreleases.json');

        $this->assertNotFalse($contents, 'Belga fixture could not be read.');

        return $contents;
    }

    private function belgaFeed(): Feed
    {
        $language = Language::factory()->create(['short_code' => 'en']);

        return Feed::factory()->create([
            'type' => 'website',
            'provider' => 'belga',
            'language_id' => $language->id,
            'url' => config('feed.providers.belga.languages.en.url'),
        ]);
    }

    public function test_creates_articles_from_belga_api_response(): void
    {
        Http::fake(['*' => Http::response($this->apiResponse(), 200)]);

        $result = $this->createFeedFetcher()->execute($this->belgaFeed());

        $this->assertCount(6, $result);
        $this->assertDatabaseHas('articles', [
            'url' => 'https://www.belganewsagency.eu/press-releases/35285/',
        ]);
        $this->assertDatabaseHas('articles', [
            'url' => 'https://www.belganewsagency.eu/press-releases/35269/',
        ]);
    }

    public function test_associates_created_articles_with_the_feed(): void
    {
        Http::fake(['*' => Http::response($this->apiResponse(), 200)]);

        $feed = $this->belgaFeed();

        $this->createFeedFetcher()->execute($feed);

        $this->assertDatabaseHas('articles', [
            'url' => 'https://www.belganewsagency.eu/press-releases/35285/',
            'feed_id' => $feed->id,
        ]);
    }

    public function test_returns_empty_collection_when_api_returns_no_articles(): void
    {
        // A well-formed envelope with nothing in it is legitimate (quiet day),
        // and must be a no-op rather than an error.
        Http::fake(['*' => Http::response('{"data":[],"_meta":{"total":0}}', 200)]);

        $result = $this->createFeedFetcher()->execute($this->belgaFeed());

        $this->assertEmpty($result);
        $this->assertDatabaseCount('articles', 0);
    }

    public function test_returns_empty_collection_when_api_returns_an_error_page(): void
    {
        // The failure mode that caused #115: a 404 HTML body reaching the parser.
        Http::fake(['*' => Http::response('<html><body>404 Not Found</body></html>', 200)]);

        $result = $this->createFeedFetcher()->execute($this->belgaFeed());

        $this->assertEmpty($result);
    }

    protected function tearDown(): void
    {
        Mockery::close();
        parent::tearDown();
    }
}
