<?php

declare(strict_types=1);

namespace Seka\Portal\Modul\Statistiky\Entities\Zaznam\ValueObjects;

use Iterator;
use JsonSerializable;

/**
 * Class ZoznamPoctuKontrolAbstract
 *
 * @package Seka\Portal\Modul\Statistiky\Entities\Zaznam\ValueObjects
 */
abstract class ZoznamPoctuKontrolAbstract implements ZoznamPoctuKontrol, Iterator, JsonSerializable
{
    /**
     * @var int
     */
    protected int $position = 0;

    /**
     * @var \Seka\Portal\Modul\Statistiky\Entities\Zaznam\ValueObjects\PocetKontrolPodlaDruhu[]
     */
    protected array $items = [];

    /**
     * ZoznamPoctuKontrolAbstract constructor.
     *
     * @param array $poctyKontrol
     */
    public function __construct(array $poctyKontrol = [])
    {
        $this->items = $poctyKontrol;
    }

    /**
     * @param \Seka\Portal\Modul\Statistiky\Entities\Zaznam\ValueObjects\PocetKontrol $pocetKontrol
     *
     * @return mixed
     */
    abstract public function add(PocetKontrol $pocetKontrol);

    /**
     * @param array $udaje
     *
     * @return static
     */
    abstract public static function createFromArray(array $udaje): self;

    /**
     * @return mixed
     */
    public function current()
    {
        return $this->items[$this->position];
    }

    /**
     *
     */
    public function next(): void
    {
        ++$this->position;
    }

    /**
     * @return bool|float|int|string|null
     */
    public function key()
    {
        return $this->position;
    }

    /**
     * @return bool
     */
    public function valid(): bool
    {
        return isset($this->items[$this->position]);
    }

    /**
     *
     */
    public function rewind(): void
    {
        $this->position = 0;
    }

    /**
     * @return string
     */
    public function jsonSerialize(): string
    {
        return json_encode($this->toArray());
    }

    /**
     * @return array
     */
    public function toArray(): array
    {
        return array_map(function (PocetKontrol $pocetKontrol) {
            return $pocetKontrol->toArray();
        }, $this->items);
    }

    /**
     * @return int
     */
    public function count(): int
    {
        return count($this->items);
    }
}
