<?php

declare(strict_types=1);

namespace App\Services;

use Illuminate\Support\Facades\Log;
use jcobhams\NewsApi\NewsApi;
use jcobhams\NewsApi\NewsApiException;

class NewsApiService
{
    private NewsApi $newsApi;

    public function __construct()
    {
        $apiKey = config('newsapi.key');

        if (empty($apiKey)) {
            throw new \RuntimeException('NewsAPI key is not configured. Please set NEWSAPI_KEY in your .env file.');
        }

        $this->newsApi = new NewsApi($apiKey);
    }

    /**
     * Get top headlines from NewsAPI
     *
     * @param array<string, mixed> $params Parameters for the API call
     * @return array<string, mixed> Response as array
     * @throws \RuntimeException
     */
    public function getTopHeadlines(array $params = []): array
    {
        try {
            $response = $this->newsApi->getTopHeadlines(
                $params['q'] ?? null,
                $params['sources'] ?? null,
                $params['country'] ?? null,
                $params['category'] ?? null,
                $params['page_size'] ?? null,
                $params['page'] ?? null
            );

            return $this->convertToArray($response);
        } catch (NewsApiException $e) {
            Log::error('NewsAPI Error (Top Headlines): ' . $e->getMessage());
            throw new \RuntimeException('Failed to fetch top headlines: ' . $e->getMessage(), 0, $e);
        }
    }

    /**
     * Get everything from NewsAPI
     *
     * @param array<string, mixed> $params Parameters for the API call
     * @return array<string, mixed> Response as array
     * @throws \RuntimeException
     */
    public function getEverything(array $params = []): array
    {
        try {
            $response = $this->newsApi->getEverything(
                $params['q'] ?? null,
                $params['sources'] ?? null,
                $params['domains'] ?? null,
                $params['exclude_domains'] ?? null,
                $params['from'] ?? null,
                $params['to'] ?? null,
                $params['language'] ?? 'en',
                $params['sort_by'] ?? null,
                $params['page_size'] ?? null,
                $params['page'] ?? null
            );

            return $this->convertToArray($response);
        } catch (NewsApiException $e) {
            Log::error('NewsAPI Error (Everything): ' . $e->getMessage());
            throw new \RuntimeException('Failed to fetch articles: ' . $e->getMessage(), 0, $e);
        }
    }

    /**
     * Get sources from NewsAPI
     *
     * @param array<string, mixed> $params Parameters for the API call
     * @return array<string, mixed> Response as array
     * @throws \RuntimeException
     */
    public function getSources(array $params = []): array
    {
        try {
            $response = $this->newsApi->getSources(
                $params['category'] ?? null,
                $params['language'] ?? null,
                $params['country'] ?? null
            );

            return $this->convertToArray($response);
        } catch (NewsApiException $e) {
            Log::error('NewsAPI Error (Sources): ' . $e->getMessage());
            throw new \RuntimeException('Failed to fetch sources: ' . $e->getMessage(), 0, $e);
        }
    }

    /**
     * Convert stdClass object to array recursively
     *
     * @param mixed $data Data to convert
     * @return array<string, mixed>
     */
    private function convertToArray(mixed $data): array
    {
        return json_decode(json_encode($data), true) ?? [];
    }
}
