<?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\ChapterRepositoryInterface;
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 ChapterRepositoryInterface $chapterRepository,
        private FileServiceInterface $fileService
    ) {}

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

        $chapter = $this->chapterRepository->findVisibleById($query->chapterId);

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

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

        // Use the actual CBZ path from the chapter
        $cbzPath = $chapter->getCbzPath();

        // Extract the existing filename from the path
        $filename = basename($cbzPath);

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

        return new DownloadResponse($httpResponse);
    }
}
