<?php

namespace idoit\Module\SyneticsJdisc\Graphql;

use GraphQL\Query;
use GraphQL\Variable;
use idoit\Module\SyneticsJdisc\Graphql\Type\AbstractType;

abstract class AbstractGraphql
{
    /**
     * @var AbstractType[]
     */
    private $parameters = [];

    /**
     * @return Query
     */
    abstract public function getQuery(): Query;

    /**
     * @return AbstractType[]
     */
    abstract public function getParameters(): array;

    /**
     * @return array
     */
    abstract public function getSelections(): array;

    /**
     * @param AbstractType[] $parameters
     *
     * @return void
     */
    public function setParameters(array $parameters): void
    {
        foreach ($parameters as $parameter) {
            $method = 'set' . ucfirst($parameter->getKey());
            if (method_exists($this, $method)) {
                $this->$method($parameter);
            }
        }
    }

    /**
     * @return array
     */
    public function getFlattenParameters(): array
    {
        $parameters = [];
        foreach ($this->getParameters() as $parameter) {
            $parameters[$parameter->getKey()] = $parameter->getFormattedValue();
        }

        return $parameters;
    }

    /**
     * @return array
     */
    public function buildArguments(): array
    {
        $arguments = [];
        foreach ($this->getParameters() as $value) {
            $arguments[$value->getKey()] = '$' . $value->getKey();
        }
        return $arguments;
    }

    /**
     * @return array
     */
    public function buildVariables(): array
    {
        $parameters = $this->getParameters();
        $variables = [];
        foreach ($parameters as $parameter) {
            $variables[] = new Variable($parameter->getKey(), $parameter::getType());
        }
        return $variables;
    }
}
