<?php

namespace App\Twig\Components;

use Aimeos\Map;
use App\Monitor\Dto\UpcomingEpisode;
use App\Monitor\Framework\Entity\Monitor;
use App\Tmdb\Tmdb;
use Carbon\CarbonImmutable;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
use Tmdb\Model\Tv\Episode;

#[AsTwigComponent]
final class UpcomingEpisodes extends AbstractController
{
    // Get active monitors
    // Search TMDB for upcoming episodes


    public function __construct(
        private readonly Tmdb $tmdb,
    ) {}

    public function getUpcomingEpisodes(int $limit = 5): array
    {
        $upcomingEpisodes = new Map();
        $monitors = $this->getMonitors();
        foreach ($monitors as $monitor) {
            $upcomingEpisodes->merge($this->getNextEpisodes($monitor));
        }

        return $upcomingEpisodes->slice(0, $limit)->toArray();
    }

    private function getMonitors()
    {
        $user = $this->getUser();
        return $user->getMonitors()->filter(
            fn (Monitor $monitor) => null === $monitor->getParent() && $monitor->isActive()
        ) ?? [];
    }

    private function getNextEpisodes(Monitor $monitor): Map
    {
        $today = CarbonImmutable::now();
        $seriesInfo = $this->tmdb->tvDetails($monitor->getTmdbId());

        switch ($monitor->getMonitorType()) {
            case "tvseason":
                $episodes = Map::from($seriesInfo->episodes[$monitor->getSeason()])
                    ->filter(function (array $episode) use ($today) {
                        $airDate = CarbonImmutable::parse($episode['air_date']);
                        return $airDate->lte($today);
                    })
                ;
                break;
            case "tvshows":
                $episodes = [];
                foreach ($seriesInfo->episodes as $season => $episodeList) {
                    $episodes = array_merge($episodes, $episodeList);
                }
                $episodes = Map::from($episodes)
                    ->filter(function (array $episode) use ($today) {
                        $airDate = CarbonImmutable::parse($episode['air_date']);
                        return $airDate->gte($today);
                    })
                ;
                break;
        }

        return $episodes->map(function (array $episode) use ($monitor) {
            return new UpcomingEpisode(
                $monitor->getTitle(),
                $episode['air_date'],
                $episode['name'],
                $episode['episode_number'],
            );
        });
    }
}
