<?php

namespace App\Download\Framework\Controller;

use App\Download\Action\Handler\DeleteDownloadHandler;
use App\Download\Action\Handler\PauseDownloadHandler;
use App\Download\Action\Handler\ResumeDownloadHandler;
use App\Download\Action\Input\DeleteDownloadInput;
use App\Download\Action\Input\DownloadMediaInput;
use App\Download\Action\Input\PauseDownloadInput;
use App\Download\Action\Input\ResumeDownloadInput;
use App\Download\Framework\Repository\DownloadRepository;
use App\Util\Broadcaster;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\Attribute\Route;

class ApiController extends AbstractController
{
    public function __construct(
        private DownloadRepository $downloadRepository,
        private MessageBusInterface $bus,
        private readonly Broadcaster $broadcaster,
    ) {}

    #[Route('/api/download', name: 'api_download', methods: ['POST'])]
    public function download(
        DownloadMediaInput $input,
    ): Response {
        $download = $this->downloadRepository->insert(
            $this->getUser(),
            $input->url,
            $input->title,
            $input->filename,
            $input->imdbId,
            $input->mediaType,
            "",
        );
        $this->downloadRepository->getEntityManager()->persist($download);
        $this->downloadRepository->getEntityManager()->flush();
        $input->downloadId = $download->getId();
        $input->userId = $this->getUser()->getId();

        try {
            $this->bus->dispatch($input->toCommand());
        } catch (\Throwable $exception) {
            return $this->json(['error' => $exception->getMessage()], Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        $this->broadcaster->alert(
            title: 'Success',
            message: "$input->title added to Queue."
        );

        return $this->json(['status' => 200, 'message' => 'Added to Queue']);
    }

    #[Route('/api/download/{downloadId}', name: 'api_download_delete', methods: ['DELETE'])]
    public function deleteDownload(
        DeleteDownloadInput $input,
        DeleteDownloadHandler $handler,
    ): Response {
        $result = $handler->handle($input->toCommand());
        $this->broadcaster->alert(
            title: 'Success',
            message: "{$result->download->getTitle()} has been deleted.",
        );

        return $this->json(['status' => 200, 'message' => 'Download Deleted']);
    }

    #[Route('/api/download/{downloadId}/pause', name: 'api_download_pause', methods: ['PATCH'])]
    public function pauseDownload(
        PauseDownloadInput $input,
        PauseDownloadHandler $handler,
    ): Response {
        $result = $handler->handle($input->toCommand());
        $this->broadcaster->alert(
            title: 'Success',
            message: "{$result->download->getTitle()} has been Paused.",
        );

        return $this->json(['status' => 200, 'message' => 'Download Paused']);
    }

    #[Route('/api/download/{downloadId}/resume', name: 'api_download_resume', methods: ['PATCH'])]
    public function resumeDownload(
        ResumeDownloadInput $input,
        ResumeDownloadHandler $handler,
    ): Response {
        $result = $handler->handle($input->toCommand());
        $this->broadcaster->alert(
            title: 'Success',
            message: "{$result->download->getTitle()} has been Resumed.",
        );

        return $this->json(['status' => 200, 'message' => 'Download Resumed']);
    }
}
