<?php

namespace Tests\Fakes;

use App\Element\CreateElementDto;
use App\Element\Element;
use App\Element\ElementRepository;
use App\Set\Set as DomainSet;

class FakeElementRepository implements ElementRepository
{
    /**
     * @var Element[]
     */
    private array $elementsById = [];

    public function create(CreateElementDto $dto): Element
    {
        $id = count($this->elementsById) + 1;
        $element = new Element(
            id: $id,
            title: $dto->title,
            set: $dto->set,
            parentElement: $dto->parentElement,
        );
        $this->elementsById[$id] = $element;

        return $element;
    }

    public function find(int $id): ?Element
    {
        if (! isset($this->elementsById[$id])) {
            return null;
        }

        return $this->cloneElement($this->elementsById[$id]);
    }

    /**
     * @return Element[]
     */
    public function findBySet(DomainSet $set): array
    {
        $elements = [];
        foreach ($this->elementsById as $element) {
            if ($element->getSet()->getId() === $set->getId()) {
                $elements[] = $this->cloneElement($element);
            }
        }

        return $elements;
    }

    private function cloneElement(Element $element): Element
    {
        $parentElement = $element->getParentElement();
        if ($parentElement !== null) {
            $parentElement = $this->cloneElement($parentElement);
        }

        return new Element(
            id: $element->getId(),
            title: $element->getTitle(),
            set: $element->getSet(),
            parentElement: $parentElement,
        );
    }
}
