<?php

namespace App\Twig\Extensions;

use App\Base\ConfigResolver;
use App\Base\Dto\AppVersionDto;
use App\Base\Service\MediaFiles;
use App\Torrentio\Action\Result\GetTvShowOptionsResult;
use App\Twig\Dto\EpisodeIdDto;
use ChrisUllyott\FileSize;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Twig\Attribute\AsTwigFilter;
use Twig\Attribute\AsTwigFunction;

class UtilExtension
{

    public function __construct(
        private readonly ConfigResolver $config,
        private readonly MediaFiles $mediaFiles,
    ) {}

    #[AsTwigFunction('app_version')]
    public function app_version(): AppVersionDto
    {
        return $this->config->getAppVersion();
    }

    #[AsTwigFunction('uniqid')]
    public function uniqid(): string
    {
        return uniqid();
    }

    #[AsTwigFilter('truncate')]
    public function truncate(string $text)
    {
        if (strlen($text) > 300) {
            $text = substr($text, 0, 300) . '...';
        }
        return $text;
    }

    #[AsTwigFilter('filesize')]
    public function type(string|int $size)
    {
        return (new FileSize($size))->asAuto();
    }

    #[AsTwigFilter('strip_media_path')]
    public function stripMediaPath(string $path)
    {
        return str_replace(
            $this->mediaFiles->getBasePath() . DIRECTORY_SEPARATOR,
            '',
            $path
        );
    }

    #[AsTwigFilter('episode_id_from_results')]
    public function episodeIdFromResults($result): ?string
    {
        if (!$result instanceof GetTvShowOptionsResult) {
            return null;
        }

        return "S". str_pad($result->season, 2, "0", STR_PAD_LEFT) .
            "E". str_pad($result->episode, 2, "0", STR_PAD_LEFT);
    }

    #[AsTwigFunction('episode_id')]
    public function episodeId($season, $episode): ?string
    {
        return "S". str_pad($season, 2, "0", STR_PAD_LEFT) .
            "E". str_pad($episode, 2, "0", STR_PAD_LEFT);
    }

    #[AsTwigFunction('episode_anchor')]
    public function episodeAnchor($season, $episode): ?string
    {
        return "episode_" . (int) $season . "_" . (int) $episode;
    }

    #[AsTwigFunction('extract_from_episode_id')]
    public function extractFromEpisodeId(?string $episodeId): ?EpisodeIdDto
    {
        if (null === $episodeId) {
            return new EpisodeIdDto("", "");
        }

        // Capture season
        $seasonMatch = [];
        preg_match('/[sS]\d\d(\d)?(\d)?/', $episodeId, $seasonMatch);
        if (empty($seasonMatch)) {
            $season = "";
        } else {
            $season = str_replace(['S', 's'], '', $seasonMatch[0]);
        }

        // Capture episode
        $episodeMatch = [];
        preg_match('/[eE]\d\d(\d)?(\d)?/', $episodeId, $episodeMatch);
        if (empty($episodeMatch)) {
            $episode = "";
        } else {
            $episode = str_replace(['E', 'e'], '', $episodeMatch[0]);
        }

        if (null === $season && null === $episode) {
            return new EpisodeIdDto("", "");
        }

        return new EpisodeIdDto($season, $episode);
    }

    #[AsTwigFunction('sentry_enabled')]
    public function sentryEnabled(): bool
    {
       $sentryConfig = $this->config->getSentryConfig();
       return $sentryConfig['javascript_url'] !== null &&
           $sentryConfig['javascript_url'] !== '';
    }

    #[AsTwigFilter('base64_encode')]
    public function base64_encode(string $data): string
    {
        return \base64_encode($data);
    }
}
