<?php

namespace Tests\Unit\Services\Parsers;

use App\Services\Parsers\BelgaHomepageParser;
use App\Services\Parsers\BelgaHomepageParserAdapter;
use Tests\TestCase;

class BelgaHomepageParserTest extends TestCase
{
    private function fixture(): string
    {
        $contents = file_get_contents(__DIR__.'/../../../Fixtures/belga-pressreleases.json');

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

        return $contents;
    }

    /**
     * @param  array<int, array<string, mixed>>  $data
     */
    private function jsonWith(array $data): string
    {
        return (string) json_encode(['data' => $data]);
    }

    public function test_extracts_article_urls_from_api_json(): void
    {
        $urls = BelgaHomepageParser::extractArticleUrls($this->fixture());

        $this->assertCount(6, $urls);
        $this->assertSame('https://www.belganewsagency.eu/press-releases/35285/', $urls[0]);
        $this->assertContains('https://www.belganewsagency.eu/press-releases/35269/', $urls);
    }

    public function test_deduplicates_urls(): void
    {
        $json = $this->jsonWith([
            ['id' => 100],
            ['id' => 100],
            ['id' => '100'],
            ['id' => 101],
        ]);

        $urls = BelgaHomepageParser::extractArticleUrls($json);

        $this->assertSame([
            'https://www.belganewsagency.eu/press-releases/100/',
            'https://www.belganewsagency.eu/press-releases/101/',
        ], $urls);
    }

    public function test_returns_empty_array_for_malformed_json(): void
    {
        $this->assertSame([], BelgaHomepageParser::extractArticleUrls('<html>404 not found</html>'));
        $this->assertSame([], BelgaHomepageParser::extractArticleUrls('{"data": ['));
        $this->assertSame([], BelgaHomepageParser::extractArticleUrls(''));
    }

    public function test_returns_empty_array_when_data_key_missing_or_empty(): void
    {
        $this->assertSame([], BelgaHomepageParser::extractArticleUrls('{}'));
        $this->assertSame([], BelgaHomepageParser::extractArticleUrls('{"data": []}'));
        $this->assertSame([], BelgaHomepageParser::extractArticleUrls('{"data": "not-an-array"}'));
    }

    public function test_skips_entries_without_usable_id(): void
    {
        $json = $this->jsonWith([
            ['id' => 200],
            ['id' => null],
            ['publishDate' => '2026-08-01T06:24:19'],
            ['id' => 'not-numeric'],
            ['id' => 201],
        ]);

        $urls = BelgaHomepageParser::extractArticleUrls($json);

        $this->assertSame([
            'https://www.belganewsagency.eu/press-releases/200/',
            'https://www.belganewsagency.eu/press-releases/201/',
        ], $urls);
    }

    public function test_adapter_delegates_and_reports_source(): void
    {
        $adapter = new BelgaHomepageParserAdapter('en');

        $this->assertSame(
            BelgaHomepageParser::extractArticleUrls($this->fixture()),
            $adapter->extractArticleUrls($this->fixture())
        );

        $this->assertTrue($adapter->canParse('https://www.belganewsagency.eu/press-releases/35285/'));
        $this->assertTrue($adapter->canParse('https://capi.belga.press/belgapress/api/public/pressreleases'));
        $this->assertFalse($adapter->canParse('https://www.vrt.be/vrtnws/en/'));
        $this->assertSame('Belga News Agency', $adapter->getSourceName());
    }

    public function test_adapter_url_comes_from_config(): void
    {
        config(['feed.providers.belga.languages.en.url' => 'https://example.test/pressreleases?count=7']);

        $this->assertSame(
            'https://example.test/pressreleases?count=7',
            (new BelgaHomepageParserAdapter('en'))->getHomepageUrl()
        );
    }

    public function test_adapter_api_url_pins_load_bearing_query_params(): void
    {
        $url = (new BelgaHomepageParserAdapter('en'))->getHomepageUrl();

        $this->assertStringStartsWith('https://capi.belga.press/belgapress/api/public/pressreleases?', $url);
        $this->assertStringContainsString('newsroomId=70', $url);
        // 0-based item index: offset=1 skipped the newest release entirely (#158).
        $this->assertStringContainsString('offset=0&', $url);
        $this->assertStringContainsString('count=50', $url);
        $this->assertStringContainsString('language=EN', $url);
    }
}
