<?php

namespace App\Domain\Manga\Application\QueryHandler;

use App\Domain\Manga\Application\Query\DownloadCbz;
use App\Domain\Manga\Application\Response\DownloadResponse;
use App\Domain\Manga\Domain\Contract\Repository\MangaRepositoryInterface;
use App\Domain\Manga\Domain\Contract\Service\FileServiceInterface;
use App\Domain\Manga\Domain\Exception\CbzFileNotFoundException;
use App\Domain\Manga\Domain\Exception\ChapterNotFoundException;
use App\Domain\Manga\Domain\Exception\ChapterNotAvailableException;
use App\Domain\Shared\Domain\Contract\QueryHandlerInterface;
use App\Domain\Shared\Domain\Contract\QueryInterface;
use App\Domain\Shared\Domain\Contract\ResponseInterface;

readonly class DownloadCbzHandler implements QueryHandlerInterface
{
    public function __construct(
        private MangaRepositoryInterface $mangaRepository,
        private FileServiceInterface $fileService
    ) {
    }

    public function handle(QueryInterface $query): ResponseInterface
    {
        assert($query instanceof DownloadCbz);

        $chapter = $this->mangaRepository->findVisibleChapterById($query->chapterId);

        if (!$chapter) {
            throw new ChapterNotFoundException($query->chapterId);
        }

        if (!$chapter->isAvailable()) {
            throw new ChapterNotAvailableException($query->chapterId);
        }

        $pagesDirectory = $chapter->getPagesDirectory();
        $filename = basename($pagesDirectory);

        try {
            $httpResponse = $this->fileService->downloadCbz($pagesDirectory, $filename);
        } catch (CbzFileNotFoundException $e) {
            throw new ChapterNotAvailableException($query->chapterId);
        }

        return new DownloadResponse($httpResponse);
    }
}
