<?php
namespace boru\boruai\Openai\Response\Parts\Content;

use boru\boruai\Openai\Models\BaseModel;
use boru\boruai\Openai\Models\ListItem;
use boru\boruai\Openai\Response\Parts\Content\InputFile;
use boru\boruai\Openai\Response\Parts\Content\InputImage;
use boru\boruai\Openai\Response\Parts\Content\InputText;
use boru\output\Output;

class Content extends BaseModel {
    private $text;
    private $body = [];

    public function __construct($input=[]) {
        if(is_array($input)) {
            $isAssociative = array_keys($input) !== range(0, count($input) - 1);
            if($isAssociative) {
                $this->body[] = self::fromArray($input);
            } else {
                foreach($input as $item) {
                    $this->body[] = self::fromArray($item);
                }
            }
        }
    }
    
    public function output() {
        $textBodies = [];
        foreach($this->body as $item) {
            if($item instanceof OutputText) {
                $textBodies[] = $item->text();
            }
        }
        if(count($textBodies) > 0) {
            return implode("\n",$textBodies);
        }
        $textBodies = [];
        foreach($this->body as $item) {
            if($item instanceof InputText) {
                $textBodies[] = $item->text();
            }
        }
        if(count($textBodies) > 0) {
            return implode("\n",$textBodies);
        }
        return false;
    }

    public function asJson($array=true) {
        $text = $this->output();
        if($text) {
            $textArray=json_decode($text,true);
            if(!$textArray) {
                return false;
            }
            if($array) {
                return $textArray;
            } else {
                return $text;
            }
        }
        return false;
    }
    public function asString() {
        $text = $this->output();
        if($text) {
            return $text;
        }
        return false;
    }
    public function __toString() {
        return $this->asString();
    }

    public function toArray() {
        $array = [];
        foreach($this->body as $item) {
            if($item instanceof BaseModel) {
                $array[] = $item->toArray();
            } else {
                $array[] = $item;
            }
        }
        return $array;
    }

    public static function fromArray($array,$allowListItem=true) {
        if(!is_array($array)) {
            return new InputText(["text"=>$array]);
        }
        if(isset($array["type"])) {
            //take "input_text" and turn it into "InputText", take "output_text" and turn it into "OutputText"
            $type = str_replace("_", "", ucwords($array["type"], "_"));
            $class = "boru\\boruai\\Openai\\Response\\Parts\\Content\\".$type;
            if(class_exists($class)) {
                return new $class($array);
            } else {
                throw new \Exception("Class $class not found");
            }
        }
        if(isset($array["text"])) {
            return new InputText($array);
        }
        if(isset($array["file"])) {
            return new InputFile($array);
        }
        if(isset($array["image"])) {
            return new InputImage($array);
        }
        if($allowListItem) {
            return new ListItem($array);
        }
        throw new \Exception("Invalid array passed to Content::fromArray");
    }
}