<?php

declare(strict_types=1);

namespace OCA\RePod\Core\EpisodeAction;

use OCA\GPodderSync\Core\EpisodeAction\EpisodeAction;

/**
 * Base: https://github.com/pbek/nextcloud-nextpod/blob/main/lib/Core/EpisodeAction/EpisodeActionExtraData.php.
 * Specs: https://github.com/Podcast-Standards-Project/PSP-1-Podcast-RSS-Specification/blob/main/README.md#required-item-elements.
 *
 * @phpstan-import-type EpisodeActionType from EpisodeAction
 *
 * @phpstan-type EpisodeActionExtraDataType = array{
 * 	title: string,
 *  url: ?string,
 *  name: string,
 *  link: ?string,
 *  image: ?string,
 *  author: ?string,
 *  description: ?string,
 *  fetchedAtUnix: int,
 * 	guid: string,
 * 	type: ?string,
 * 	size: ?int,
 * 	pubDate: ?\DateTime,
 * 	duration: ?string,
 *  action: ?EpisodeActionType
 * }
 */
class EpisodeActionExtraData implements \JsonSerializable, \Stringable
{
	public function __construct(
		private readonly string $title,
		private readonly ?string $url,
		private readonly string $name,
		private readonly ?string $link,
		private readonly ?string $image,
		private readonly ?string $author,
		private readonly ?string $description,
		private readonly int $fetchedAtUnix,
		private readonly string $guid,
		private readonly ?string $type,
		private readonly ?int $size,
		private readonly ?\DateTime $pubDate,
		private readonly ?string $duration,
		private readonly ?EpisodeAction $action
	) {}

	public function __toString(): string {
		return $this->url ?? '/no episodeUrl/';
	}

	public function getTitle(): string {
		return $this->title;
	}

	public function getUrl(): ?string {
		return $this->url;
	}

	public function getName(): string {
		return $this->name;
	}

	public function getLink(): ?string {
		return $this->link;
	}

	public function getImage(): ?string {
		return $this->image;
	}

	public function getAuthor(): ?string {
		return $this->author;
	}

	public function getDescription(): ?string {
		return $this->description;
	}

	public function getFetchedAtUnix(): int {
		return $this->fetchedAtUnix;
	}

	public function getGuid(): string {
		return $this->guid;
	}

	public function getType(): ?string {
		return $this->type;
	}

	public function getSize(): ?int {
		return $this->size;
	}

	public function getPubDate(): ?\DateTime {
		return $this->pubDate;
	}

	public function getDuration(): ?string {
		return $this->duration;
	}

	public function getAction(): ?EpisodeAction {
		return $this->action;
	}

	/**
	 * @return EpisodeActionExtraDataType
	 */
	public function toArray(): array {
		return
		[
			'title' => $this->title,
			'url' => $this->url,
			'name' => $this->name,
			'link' => $this->link,
			'image' => $this->image,
			'author' => $this->author,
			'description' => $this->description,
			'fetchedAtUnix' => $this->fetchedAtUnix,
			'guid' => $this->guid,
			'type' => $this->type,
			'size' => $this->size,
			'pubDate' => $this->pubDate,
			'duration' => $this->duration,
			'action' => $this->action instanceof EpisodeAction ? $this->action->toArray() : null,
		];
	}

	/**
	 * @return EpisodeActionExtraDataType
	 */
	public function jsonSerialize(): mixed {
		return $this->toArray();
	}
}
