<?php

declare(strict_types=1);

namespace App\Module\Agency\Service\Adapter;

class RssAgencyAdapter implements AgencyAdapterInterface
{
    public const PREDEFINED_FEEDS = [
        'trt_haber' => [
            'name' => 'TRT Haber',
            'url' => 'https://www.trthaber.com/sondakika.rss',
            'icon' => 'fas fa-tv',
            'color' => '#1a73e8',
        ],
        'cumhuriyet' => [
            'name' => 'Cumhuriyet',
            'url' => 'https://www.cumhuriyet.com.tr/rss',
            'icon' => 'fas fa-newspaper',
            'color' => '#dc2626',
        ],
        'ntv' => [
            'name' => 'NTV',
            'url' => 'https://www.ntv.com.tr/son-dakika.rss',
            'icon' => 'fas fa-broadcast-tower',
            'color' => '#f59e0b',
        ],
        'haberturk' => [
            'name' => 'Haberturk',
            'url' => 'https://www.haberturk.com/rss',
            'icon' => 'fas fa-satellite-dish',
            'color' => '#0891b2',
        ],
        'hurriyet' => [
            'name' => 'Hurriyet',
            'url' => 'https://www.hurriyet.com.tr/rss/anasayfa',
            'icon' => 'fas fa-globe',
            'color' => '#7c3aed',
        ],
    ];

    private array $config = [];

    public function getSlug(): string
    {
        return 'rss';
    }

    public function getName(): string
    {
        return 'RSS Haber Kaynaklari (Ucretsiz)';
    }

    public function configure(array $config): void
    {
        $this->config = $config;
    }

    public function fetchLatest(\DateTimeInterface $since): array
    {
        $extraConfig = $this->config['config'] ?? [];
        $feeds = $extraConfig['feeds'] ?? [];
        $customFeeds = $extraConfig['custom_feeds'] ?? [];

        // Eger hic feed yoksa, varsayilan olarak TRT Haber'i kullan
        if (empty($feeds) && empty($customFeeds)) {
            $feeds = [
                ['name' => 'TRT Haber', 'url' => self::PREDEFINED_FEEDS['trt_haber']['url'], 'enabled' => true],
            ];
        }

        $allItems = [];

        // Hazir feed'leri cek
        foreach ($feeds as $feed) {
            if (empty($feed['enabled']) || empty($feed['url'])) {
                continue;
            }
            $items = $this->parseFeed($feed['url'], $feed['name'] ?? 'RSS', $since);
            $allItems = array_merge($allItems, $items);
        }

        // Ozel feed'leri cek
        foreach ($customFeeds as $feed) {
            if (empty($feed['enabled']) || empty($feed['url'])) {
                continue;
            }
            $items = $this->parseFeed($feed['url'], $feed['name'] ?? 'Ozel RSS', $since);
            $allItems = array_merge($allItems, $items);
        }

        return $allItems;
    }

    public function fetchById(string $externalId): ?array
    {
        return null;
    }

    public function testConnection(): bool
    {
        $extraConfig = $this->config['config'] ?? [];
        $feeds = $extraConfig['feeds'] ?? [];
        $customFeeds = $extraConfig['custom_feeds'] ?? [];

        // Test icin en az bir aktif feed olmalı
        $testUrl = null;

        foreach ($feeds as $feed) {
            if (!empty($feed['enabled']) && !empty($feed['url'])) {
                $testUrl = $feed['url'];
                break;
            }
        }

        if (!$testUrl) {
            foreach ($customFeeds as $feed) {
                if (!empty($feed['enabled']) && !empty($feed['url'])) {
                    $testUrl = $feed['url'];
                    break;
                }
            }
        }

        // Eger API URL alani doldurulduysa onu test et
        if (!$testUrl && !empty($this->config['api_url'])) {
            $testUrl = $this->config['api_url'];
        }

        if (!$testUrl) {
            return false;
        }

        return $this->isValidFeed($testUrl);
    }

    /**
     * RSS/Atom feed'i parse eder ve item dizisi dondurur.
     */
    private function parseFeed(string $url, string $sourceName, \DateTimeInterface $since): array
    {
        $items = [];

        try {
            $context = stream_context_create([
                'http' => [
                    'timeout' => 15,
                    'user_agent' => 'HaberCMS/1.0 RSS Reader',
                    'follow_location' => true,
                ],
                'ssl' => [
                    'verify_peer' => false,
                    'verify_peer_name' => false,
                ],
            ]);

            $content = @file_get_contents($url, false, $context);
            if ($content === false) {
                return [];
            }

            // BOM karakterini temizle
            $content = preg_replace('/^\xEF\xBB\xBF/', '', $content);

            libxml_use_internal_errors(true);
            $xml = simplexml_load_string($content);
            if ($xml === false) {
                return [];
            }

            // Atom format mi kontrol et
            if (isset($xml->entry)) {
                $items = $this->parseAtomFeed($xml, $sourceName, $since);
            }
            // RSS 2.0 format
            elseif (isset($xml->channel->item)) {
                $items = $this->parseRssFeed($xml, $sourceName, $since);
            }
        } catch (\Exception $e) {
            // Hata durumunda bos dizi dondur
        }

        return $items;
    }

    /**
     * RSS 2.0 formatindaki feed'i parse eder.
     */
    private function parseRssFeed(\SimpleXMLElement $xml, string $sourceName, \DateTimeInterface $since): array
    {
        $items = [];
        $namespaces = $xml->getNamespaces(true);

        foreach ($xml->channel->item as $entry) {
            try {
                // Tarih kontrolu
                $pubDate = null;
                if (!empty((string) $entry->pubDate)) {
                    try {
                        $pubDate = new \DateTimeImmutable((string) $entry->pubDate);
                        if ($pubDate < $since) {
                            continue;
                        }
                    } catch (\Exception $e) {
                        // Tarih parse edilemezse devam et
                    }
                }

                $title = trim((string) $entry->title);
                if (empty($title)) {
                    continue;
                }

                // Gorsel bul
                $images = [];

                // enclosure etiketi
                if (isset($entry->enclosure)) {
                    $encUrl = (string) $entry->enclosure['url'];
                    if (!empty($encUrl)) {
                        $images[] = $encUrl;
                    }
                }

                // imageUrl etiketi (TRT Haber)
                if (isset($entry->imageUrl)) {
                    $imgUrl = (string) $entry->imageUrl;
                    if (!empty($imgUrl)) {
                        $images[] = $imgUrl;
                    }
                }

                // media:content
                if (isset($namespaces['media'])) {
                    $media = $entry->children($namespaces['media']);
                    if (isset($media->content)) {
                        $mediaUrl = (string) $media->content['url'];
                        if (!empty($mediaUrl)) {
                            $images[] = $mediaUrl;
                        }
                    }
                    if (isset($media->thumbnail)) {
                        $thumbUrl = (string) $media->thumbnail['url'];
                        if (!empty($thumbUrl)) {
                            $images[] = $thumbUrl;
                        }
                    }
                }

                // Benzersiz gorseller
                $images = array_values(array_unique($images));

                // Icerik
                $content = '';
                if (isset($namespaces['content'])) {
                    $contentNs = $entry->children($namespaces['content']);
                    if (isset($contentNs->encoded)) {
                        $content = (string) $contentNs->encoded;
                    }
                }

                // Description
                $summary = trim(strip_tags((string) $entry->description));

                // Eger content bossa description'i kullan
                if (empty($content)) {
                    $content = (string) $entry->description;
                }

                // Kategori
                $category = trim((string) $entry->category);

                // External ID olustur
                $guid = (string) $entry->guid ?: (string) $entry->link;
                $externalId = md5($sourceName . '_' . $guid);

                $items[] = [
                    'external_id' => $externalId,
                    'title' => $title,
                    'content' => $content ?: null,
                    'summary' => $summary ?: null,
                    'category' => !empty($category) ? $category : $sourceName,
                    'images' => !empty($images) ? $images : null,
                    'source_name' => $sourceName,
                    'source_url' => (string) $entry->link,
                    'published_at' => $pubDate ? $pubDate->format('Y-m-d H:i:s') : null,
                ];
            } catch (\Exception $e) {
                continue;
            }
        }

        return $items;
    }

    /**
     * Atom formatindaki feed'i parse eder.
     */
    private function parseAtomFeed(\SimpleXMLElement $xml, string $sourceName, \DateTimeInterface $since): array
    {
        $items = [];

        foreach ($xml->entry as $entry) {
            try {
                // Tarih kontrolu
                $pubDate = null;
                $dateStr = (string) ($entry->published ?: $entry->updated);
                if (!empty($dateStr)) {
                    try {
                        $pubDate = new \DateTimeImmutable($dateStr);
                        if ($pubDate < $since) {
                            continue;
                        }
                    } catch (\Exception $e) {
                        // Tarih parse edilemezse devam et
                    }
                }

                $title = trim((string) $entry->title);
                if (empty($title)) {
                    continue;
                }

                // Gorsel bul
                $images = [];
                if (isset($entry->enclosure)) {
                    $encUrl = (string) $entry->enclosure['url'];
                    if (!empty($encUrl)) {
                        $images[] = $encUrl;
                    }
                }

                // Content
                $content = '';
                if (isset($entry->content)) {
                    $content = (string) $entry->content;
                }

                // Summary
                $summary = trim(strip_tags((string) $entry->summary));

                if (empty($content)) {
                    $content = (string) $entry->summary;
                }

                // Kategori
                $category = '';
                if (isset($entry->category)) {
                    $category = (string) $entry->category['term'];
                }

                // Link
                $link = '';
                if (isset($entry->link)) {
                    $link = (string) $entry->link['href'];
                }

                // External ID
                $entryId = (string) $entry->id ?: $link;
                $externalId = md5($sourceName . '_' . $entryId);

                $items[] = [
                    'external_id' => $externalId,
                    'title' => $title,
                    'content' => $content ?: null,
                    'summary' => $summary ?: null,
                    'category' => !empty($category) ? $category : $sourceName,
                    'images' => !empty($images) ? $images : null,
                    'source_name' => $sourceName,
                    'source_url' => $link,
                    'published_at' => $pubDate ? $pubDate->format('Y-m-d H:i:s') : null,
                ];
            } catch (\Exception $e) {
                continue;
            }
        }

        return $items;
    }

    /**
     * Bir URL'nin gecerli RSS/Atom feed'i olup olmadigini kontrol eder.
     */
    private function isValidFeed(string $url): bool
    {
        try {
            $context = stream_context_create([
                'http' => [
                    'timeout' => 10,
                    'user_agent' => 'HaberCMS/1.0 RSS Reader',
                    'follow_location' => true,
                ],
                'ssl' => [
                    'verify_peer' => false,
                    'verify_peer_name' => false,
                ],
            ]);

            $content = @file_get_contents($url, false, $context);
            if ($content === false) {
                return false;
            }

            $content = preg_replace('/^\xEF\xBB\xBF/', '', $content);

            libxml_use_internal_errors(true);
            $xml = simplexml_load_string($content);
            if ($xml === false) {
                return false;
            }

            // RSS veya Atom olup olmadigini kontrol et
            return isset($xml->channel->item) || isset($xml->entry);
        } catch (\Exception $e) {
            return false;
        }
    }
}
