<?php

declare(strict_types=1);

namespace App\Tests\Domain\Reader\Adapter;

use App\Domain\Reader\Domain\Contract\Repository\ChapterRepositoryInterface;
use App\Domain\Reader\Domain\Exception\ChapterNotFoundException;
use App\Domain\Reader\Domain\Model\ChapterContext;
use App\Domain\Reader\Domain\Model\Page;
use App\Domain\Reader\Domain\ValueObject\ChapterId;

final class InMemoryChapterRepository implements ChapterRepositoryInterface
{
    /** @var array<string, array{pages: array<Page>, context: ChapterContext}> */
    private array $chapters = [];

    public function addChapter(ChapterId $chapterId, ChapterContext $context, array $pages): void
    {
        $this->chapters[$chapterId->getValue()] = [
            'pages' => $pages,
            'context' => $context
        ];
    }

    public function getPagesForChapter(ChapterId $chapterId, int $page = 1, int $itemsPerPage = 20): array
    {
        if (!isset($this->chapters[$chapterId->getValue()])) {
            return [];
        }

        $pages = $this->chapters[$chapterId->getValue()]['pages'];
        $offset = ($page - 1) * $itemsPerPage;

        return array_slice($pages, $offset, $itemsPerPage);
    }

    public function getChapterContext(ChapterId $chapterId): ChapterContext
    {
        if (!isset($this->chapters[$chapterId->getValue()])) {
            throw ChapterNotFoundException::forChapter($chapterId);
        }

        return $this->chapters[$chapterId->getValue()]['context'];
    }

    public function getTotalPagesForChapter(ChapterId $chapterId): int
    {
        if (!isset($this->chapters[$chapterId->getValue()])) {
            return 0;
        }

        return count($this->chapters[$chapterId->getValue()]['pages']);
    }

    public function getPreviousChapterId(ChapterId $chapterId): ?ChapterId
    {
        $currentChapter = $this->getChapterContext($chapterId);
        $currentNumber = $currentChapter->getNumber();

        $previousChapter = null;
        $previousNumber = 0.0;

        foreach ($this->chapters as $id => $chapter) {
            $number = $chapter['context']->getNumber();
            if ($number < $currentNumber && $number > $previousNumber) {
                $previousChapter = $id;
                $previousNumber = $number;
            }
        }

        return $previousChapter ? new ChapterId($previousChapter) : null;
    }

    public function getNextChapterId(ChapterId $chapterId): ?ChapterId
    {
        $currentChapter = $this->getChapterContext($chapterId);
        $currentNumber = $currentChapter->getNumber();

        $nextChapter = null;
        $nextNumber = PHP_FLOAT_MAX;

        foreach ($this->chapters as $id => $chapter) {
            $number = $chapter['context']->getNumber();
            if ($number > $currentNumber && $number < $nextNumber) {
                $nextChapter = $id;
                $nextNumber = $number;
            }
        }

        return $nextChapter ? new ChapterId($nextChapter) : null;
    }

}
