<?php
namespace boru\ai\Embedding;

class EmbeddingRequest
{
    /** @var string|null */
    protected $provider;

    /** @var string|null */
    protected $model;

    /** @var array */
    protected $inputs = array();

    /** @var array */
    protected $options = array();

    /** @var array */
    protected $metadata = array();

    public function provider($value = null)
    {
        if ($value !== null) {
            $this->provider = (string)$value;
            return $this;
        }
        return $this->provider;
    }

    public function model($value = null)
    {
        if ($value !== null) {
            $this->model = (string)$value;
            return $this;
        }
        return $this->model;
    }

    public function input($value = null)
    {
        if ($value !== null) {
            $this->inputs = array();
            return $this->addInput($value);
        }

        if (empty($this->inputs)) {
            return null;
        }

        return $this->inputs[0];
    }

    public function inputs(array $values = null)
    {
        if ($values !== null) {
            $this->inputs = array();
            foreach ($values as $value) {
                $this->addInput($value);
            }
            return $this;
        }
        return $this->inputs;
    }

    public function addInput($value)
    {
        if (is_object($value) && !method_exists($value, '__toString')) {
            throw new \InvalidArgumentException('Embedding input must be scalar or stringable');
        }

        if (is_array($value)) {
            throw new \InvalidArgumentException('Embedding input must be scalar or stringable');
        }

        $this->inputs[] = (string)$value;
        return $this;
    }

    public function option($key = null, $value = null)
    {
        if ($key === null) {
            return $this->options;
        }

        if (is_array($key)) {
            $this->options = $key;
            return $this;
        }

        if (func_num_args() > 1) {
            $this->options[(string)$key] = $value;
            return $this;
        }

        return array_key_exists($key, $this->options) ? $this->options[$key] : null;
    }

    public function metadata($key = null, $value = null)
    {
        if ($key === null) {
            return $this->metadata;
        }

        if (is_array($key)) {
            $this->metadata = $key;
            return $this;
        }

        if (func_num_args() > 1) {
            $this->metadata[(string)$key] = $value;
            return $this;
        }

        return array_key_exists($key, $this->metadata) ? $this->metadata[$key] : null;
    }

    public function copy()
    {
        $copy = new self();
        $copy->provider($this->provider());
        $copy->model($this->model());
        $copy->inputs($this->inputs());
        $copy->option($this->option());
        $copy->metadata($this->metadata());
        return $copy;
    }
}
