<?php

namespace App\Domain\Manga\Domain\Contract\Repository;

use App\Domain\Manga\Application\Query\MonitoringCriteria;
use App\Domain\Manga\Domain\Model\Manga;
use App\Domain\Manga\Domain\Model\Chapter;
use App\Domain\Manga\Domain\Model\ValueObject\ExternalId;
use App\Domain\Manga\Domain\Model\ValueObject\MangaSlug;

interface MangaRepositoryInterface
{
    // --- Manga ---

    public function findAll(int $page = 1, int $limit = 20, string $sortBy = 'title', string $sortOrder = 'asc'): array;
    public function count(): int;
    public function findById(string $id): ?Manga;
    public function findBySlug(MangaSlug $slug): ?Manga;
    public function findByExternalId(ExternalId $externalId): ?Manga;
    public function save(Manga $manga): void;
    public function delete(Manga $manga): void;
    public function search(string $query, int $page = 1, int $limit = 20): array;
    public function countSearch(string $query): int;

    /**
     * @return Manga[]
     */
    public function findByMonitoringCriteria(MonitoringCriteria $criteria): array;

    // --- Chapters (read) ---

    public function findChapters(string $mangaId, int $page = 1, int $limit = 20, string $sortOrder = 'desc'): array;

    /**
     * @return Chapter[]
     */
    public function findAllChapters(string $mangaId, string $sortOrder = 'desc'): array;
    public function countChapters(string $mangaId): int;
    public function countAvailableChapters(string $mangaId): int;
    public function findChapterById(string $id): ?Chapter;
    public function findVisibleChapterById(string $id): ?Chapter;
    public function findChapterByMangaIdAndNumber(string $mangaId, float $chapterNumber): ?Chapter;

    /**
     * @param float[] $chapterNumbers
     * @return array<float, Chapter>
     */
    public function findExistingChaptersByNumbers(string $mangaId, array $chapterNumbers): array;

    /**
     * @return Chapter[]
     */
    public function findChaptersByMangaIdAndVolume(string $mangaId, int $volume): array;

    /**
     * @return Chapter[]
     */
    public function findVisibleChaptersByMangaIdAndVolume(string $mangaId, int $volume): array;

    /**
     * @return Chapter[]
     */
    public function findVisibleChaptersWithPagesByMangaIdAndVolume(string $mangaId, int $volume): array;

}
