<?php

namespace App\Controller;

use App\Torrentio\Action\Handler\GetMovieOptionsHandler;
use App\Torrentio\Action\Handler\GetTvShowOptionsHandler;
use App\Torrentio\Action\Input\GetMovieOptionsInput;
use App\Torrentio\Action\Input\GetTvShowOptionsInput;
use App\Torrentio\Exception\TorrentioRateLimitException;
use App\Util\Broadcaster;
use Carbon\Carbon;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;

final class TorrentioController extends AbstractController
{
    public function __construct(
        private readonly GetMovieOptionsHandler $getMovieOptionsHandler,
        private readonly GetTvShowOptionsHandler $getTvShowOptionsHandler,
        private readonly Broadcaster $broadcaster,
    ) {}

    #[Route('/torrentio/movies/{tmdbId}/{imdbId}', name: 'app_torrentio_movies')]
    public function movieOptions(GetMovieOptionsInput $input, CacheInterface $cache): Response
    {
        $cacheId = sprintf(
            "page.torrentio.movies.%s.%s",
            $input->tmdbId,
            $input->imdbId
        );

        return $cache->get($cacheId, function (ItemInterface $item) use ($input) {
            $item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
            $results = $this->getMovieOptionsHandler->handle($input->toCommand());
            return $this->render('torrentio/movies.html.twig', [
                'results' => $results,
            ]);
        });
    }

    #[Route('/torrentio/tvshows/{tmdbId}/{imdbId}/{season?}/{episode?}', name: 'app_torrentio_tvshows')]
    public function tvShowOptions(GetTvShowOptionsInput $input, CacheInterface $cache): Response
    {
        $cacheId = sprintf(
            "page.torrentio.tvshows.%s.%s.%s.%s",
            $input->tmdbId,
            $input->imdbId,
            $input->season,
            $input->episode,
        );

        try {
            return $cache->get($cacheId, function (ItemInterface $item) use ($input) {
                $item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
                $results = $this->getTvShowOptionsHandler->handle($input->toCommand());
                return $this->render('torrentio/tvshows.html.twig', [
                    'results' => $results,
                ]);
            });
        } catch (TorrentioRateLimitException $exception) {
            $this->broadcaster->alert('Warning', 'Torrentio has rate limited your requests. Please wait a few minutes before trying again.', 'warning');
            return $this->render('bare.html.twig',
                [],
                new Response('Too many requests',
                    Response::HTTP_TOO_MANY_REQUESTS,
                    ['Retry-After' => 4000]
                )
            );
        }
    }

    #[Route('/torrentio/tvshows/clear/{tmdbId}/{imdbId}/{season?}/{episode?}', name: 'app_clear_torrentio_tvshows')]
    public function clearTvShowOptions(GetTvShowOptionsInput $input, CacheInterface $cache, Request $request): Response
    {
        $cacheId = sprintf(
            "page.torrentio.tvshows.%s.%s.%s.%s",
            $input->tmdbId,
            $input->imdbId,
            $input->season,
            $input->episode,
        );
        $cache->delete($cacheId);

        $this->broadcaster->alert(
            title: 'Success',
            message: 'Torrentio cache Cleared.'
        );

        return $cache->get($cacheId, function (ItemInterface $item) use ($input) {
            $item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
            $results = $this->getTvShowOptionsHandler->handle($input->toCommand());
            return $this->render('torrentio/tvshows.html.twig', [
                'results' => $results,
            ]);
        });
    }
}
