<?php

declare(strict_types=1);

namespace OCA\RePod\Core\EpisodeAction;

use OCA\GPodderSync\Core\EpisodeAction\EpisodeActionReader as GPodderSyncEpisodeActionReader;
use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionRepository;
use OCA\RePod\Service\UserService;

class EpisodeActionReader extends GPodderSyncEpisodeActionReader
{
	public function __construct(
		private EpisodeActionRepository $episodeActionRepository,
		private UserService $userService
	) {
	}

	/**
	 * https://github.com/pbek/nextcloud-nextpod/blob/main/lib/Core/EpisodeAction/EpisodeActionExtraData.php#L119.
	 *
	 * @throws \Exception if the XML data could not be parsed
	 */
	public function parseRssXml(string $xmlString, ?int $fetchedAtUnix = null): array
	{
		$episodes = [];
		$xml = new \SimpleXMLElement($xmlString);
		$channel = $xml->channel;
		$episodeName = null;
		$episodeLink = null;
		$episodeImage = null;
		$episodeDescription = null;

		// Find episode by url and add data for it
		/** @var \SimpleXMLElement $item */
		foreach ($channel->item as $item) {
			$episodeUrl = (string) $item->enclosure['url'];

			// Get episode action
			$episodeAction = $this->episodeActionRepository->findByEpisodeUrl($episodeUrl, $this->userService->getUserUID());

			// Get episode name
			$episodeName = $this->stringOrNull($item->title);

			// Get episode link
			$episodeLink = $this->stringOrNull($item->link);

			// Get episode image
			$episodeImageChildren = $item->children('http://www.itunes.com/dtds/podcast-1.0.dtd');
			if ($episodeImageChildren) {
				$episodeImageAttributes = (array) $episodeImageChildren->image->attributes();
				$episodeImage = $this->stringOrNull(array_key_exists('href', $episodeImageAttributes) ? (string) $episodeImageAttributes['href'] : '');
				$iTunesChildren = $item->children('itunes', true);

				if ($iTunesChildren && !$episodeImage) {
					$episodeImage = $this->stringOrNull((string) $iTunesChildren->image['href']);
				}

				if (!$episodeImage) {
					$episodeImage = $this->stringOrNull($channel->image->url);
				}

				if ($iTunesChildren && !$episodeImage) {
					$episodeImage = $this->stringOrNull((string) $iTunesChildren->image['href']);
				}

				if (!$episodeImage) {
					$channelImageChildren = $channel->children('http://www.itunes.com/dtds/podcast-1.0.dtd');
					if ($channelImageChildren) {
						$episodeImageAttributes = (array) $channelImageChildren->image->attributes();
						$episodeImage = $this->stringOrNull(array_key_exists('href', $episodeImageAttributes) ? (string) $episodeImageAttributes['href'] : '');
					}
				}

				if (!$episodeImage) {
					preg_match('/<itunes:image\s+href="([^"]+)"/', $xmlString, $matches);
					$episodeImage = $this->stringOrNull($matches[1]);
				}
			}

			// Get episode description
			$episodeContentChildren = $item->children('content', true);

			if ($episodeContentChildren) {
				$episodeDescription = $this->stringOrNull($episodeContentChildren->encoded);
			}

			if (!$episodeDescription) {
				$episodeDescription = $this->stringOrNull($item->description);
			}

			// Open links in new browser window/tab
			$episodeDescription = str_replace('<a ', '<a class="description-link" target="_blank" ', $episodeDescription ?? '');

			$episodes[] = new EpisodeActionExtraData(
				$episodeUrl,
				$this->stringOrNull($channel->title),
				$episodeName,
				$episodeLink,
				$episodeImage,
				$episodeDescription,
				$fetchedAtUnix ?? (new \DateTime())->getTimestamp(),
				$episodeAction
			);
		}

		return $episodes;
	}

	private function stringOrNull(mixed $value): ?string
	{
		if ($value) {
			return (string) $value;
		}

		return null;
	}
}