<?php

namespace App\Monitor\Action\Handler;

use App\EventLog\Action\Command\AddEventLogCommand;
use App\Monitor\Action\Command\AddMonitorCommand;
use App\Monitor\Action\Result\AddMonitorResult;
use App\Monitor\Framework\Entity\Monitor;
use App\Monitor\Framework\Repository\MonitorRepository;
use App\Monitor\MonitorEvents;
use App\Tmdb\TmdbClient;
use App\User\Framework\Repository\UserRepository;
use DateTimeImmutable;
use OneToMany\RichBundle\Contract\CommandInterface;
use OneToMany\RichBundle\Contract\HandlerInterface;
use OneToMany\RichBundle\Contract\ResultInterface;
use Symfony\Component\Messenger\MessageBusInterface;

/** @implements HandlerInterface<AddMonitorCommand> */
readonly class AddMonitorHandler implements HandlerInterface
{
    public function __construct(
        private MessageBusInterface $bus,
        private MonitorRepository $movieMonitorRepository,
        private UserRepository $userRepository,
        private TmdbClient $tmdb,
    ) {}

    public function handle(CommandInterface $command): ResultInterface
    {
        $user = $this->userRepository->find($command->userId);
        $poster = $this->getPoster($command->imdbId);

        $monitor = (new Monitor())
            ->setUser($user)
            ->setPoster($poster)
            ->setTmdbId($command->tmdbId)
            ->setImdbId($command->imdbId)
            ->setTitle($command->title)
            ->setMonitorType($command->monitorType)
            ->setSeason($command->season)
            ->setEpisode($command->episode)
            ->setCreatedAt(new DateTimeImmutable())
            ->setSearchCount(0)
            ->setStatus('New');

        $this->bus->dispatch(new AddEventLogCommand(
            $user,
            MonitorEvents::MONITOR_ADDED->type(),
            MonitorEvents::MONITOR_ADDED->message(),
            (array) $monitor
        ));

        $this->movieMonitorRepository->getEntityManager()->persist($monitor);
        $this->movieMonitorRepository->getEntityManager()->flush();

        return new AddMonitorResult(
            status: 'OK',
            result: [
                'monitor' => $monitor,
            ]
        );
    }

    private function getPoster(string $imdbId): ?string
    {
        $data = $this->tmdb->tvShowDetails($imdbId);
        return $data->poster;
    }
}
