<?php

namespace App\Services\Factories;

use App\Contracts\ArticleParserInterface;
use App\Models\Feed;
use App\Services\Parsers\BelgaArticleParser;
use App\Services\Parsers\GuardianArticleParser;
use App\Services\Parsers\VrtArticleParser;
use Exception;

class ArticleParserFactory
{
    /**
     * @var array<int, class-string<ArticleParserInterface>>
     */
    private static array $parsers = [
        VrtArticleParser::class,
        BelgaArticleParser::class,
        GuardianArticleParser::class,
    ];

    /**
     * @throws Exception
     */
    public static function getParser(string $url): ArticleParserInterface
    {
        foreach (self::$parsers as $parserClass) {
            $parser = new $parserClass;

            if ($parser->canParse($url)) {
                return $parser;
            }
        }

        throw new Exception("No parser found for URL: {$url}");
    }

    public static function getParserForFeed(Feed $feed, string $parserType = 'article'): ?ArticleParserInterface
    {
        if (! $feed->provider) {
            return null;
        }

        $providerConfig = config("feed.providers.{$feed->provider}");
        if (! $providerConfig || ! isset($providerConfig['parsers'][$parserType])) {
            return null;
        }

        /** @var class-string<ArticleParserInterface> $parserClass */
        $parserClass = $providerConfig['parsers'][$parserType];
        if (! class_exists($parserClass)) {
            return null;
        }

        return new $parserClass;
    }

    /**
     * @return array<int, string>
     */
    public static function getSupportedSources(): array
    {
        return array_map(function ($parserClass) {
            $parser = new $parserClass;

            return $parser->getSourceName();
        }, self::$parsers);
    }

    /**
     * @param  class-string<ArticleParserInterface>  $parserClass
     */
    public static function registerParser(string $parserClass): void
    {
        if (! in_array($parserClass, self::$parsers)) {
            self::$parsers[] = $parserClass;
        }
    }
}
