<?php
namespace boru\ai\Schema;

class Message
{
    /** @var string */
    protected $role = 'user';

    /** @var ContentPart[] */
    protected $parts = array();

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

    public function __construct($role = 'user', $parts = array(), $metadata = array())
    {
        $this->role = (string)$role;
        if (is_array($metadata)) {
            $this->metadata = $metadata;
        }
        $this->parts($parts);
    }

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

    public function addPart($part)
    {
        if ($part instanceof ContentPart) {
            $this->parts[] = $part;
            return $this;
        }

        if (is_string($part)) {
            $this->parts[] = new ContentPart('text', $part);
            return $this;
        }

        if (is_array($part)) {
            $type = isset($part['type']) ? $part['type'] : 'text';
            $value = isset($part['value']) ? $part['value'] : (isset($part['text']) ? $part['text'] : null);
            $metadata = isset($part['metadata']) && is_array($part['metadata']) ? $part['metadata'] : array();
            $this->parts[] = new ContentPart($type, $value, $metadata);
            return $this;
        }

        throw new \InvalidArgumentException('Invalid message part');
    }

    public function parts($parts = null)
    {
        if ($parts !== null) {
            $this->parts = array();
            if (is_array($parts)) {
                foreach ($parts as $part) {
                    $this->addPart($part);
                }
            } else {
                $this->addPart($parts);
            }
            return $this;
        }
        return $this->parts;
    }

    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[$key] = $value;
            return $this;
        }
        return isset($this->metadata[$key]) ? $this->metadata[$key] : null;
    }

    public function toArray()
    {
        $parts = array();
        foreach ($this->parts() as $part) {
            $parts[] = $part instanceof ContentPart ? $part->toArray() : $part;
        }

        return array(
            'role' => $this->role(),
            'parts' => $parts,
            'metadata' => $this->metadata(),
        );
    }
}
