<?php

namespace CouponsPlus\App\Coupon\Tree;

use CouponsPlus\App\Coupon\TestableData;
use CouponsPlus\App\Coupon\Tree\Abilities;
use CouponsPlus\App\Coupon\Tree\Abilities\Branch;
use JsonSerializable;

class NodeData implements Abilities\NodeData, JsonSerializable
{
    protected ?Branch $parentBranch = null;
    protected int $virtualInstanceIndex = 0;
    private $testableGroupData;
    private $branch;

    /**
     * @param Abilities\TestableGroupData|Abilities\TestableData $testableData
     * @param Branch $branch
     */
    public function __construct($testableData, Branch $branch)
    {
        $this->testableGroupData = $testableData;
        $this->branch = $branch;

        $this->testableGroupData->setNode($this);
        $this->branch->setNode($this);
    }

    public function setParent(?Branch $parent): void
    {
        $this->parentBranch = $parent;
    }

    public function getBranch(): Branch
    {
        return $this->branch;
    }


    public function getParent(): ?Branch
    {
        return $this->parentBranch;
    }

    /**
     * @return Abilities\TestableGroupData|Abilities\TestableData
     */
    public function getTestable()
    {
        // if this is a node inside a tiered branch, return a context
        if ($this->isTier()) {
            return new TestableGroupData(
                'context',
                $this->testableGroupData->canFilterItems()? 'filter' : 'test',
                [$this->testableGroupData]
            );
        }

        return $this->testableGroupData;
    }

    public function isTier() : bool
    {
        return $this->parentBranch && $this->parentBranch->is('tiered');
    }

    #[\ReturnTypeWillChange]
    public function jsonSerialize() : array
    {
        return get_object_vars($this);
    }

    public function setVirtualInstanceIndex(int $index): void
    {
        $this->virtualInstanceIndex = $index;
    }

    public function getID(): string
    {
        return $this->getTestable()->getID();
    }
}