<?php
namespace boru\boruai\Openai\Models;

use boru\boruai\Openai\Api\Responses\ApiBaseResponse;
use boru\boruai\Openai\OpenAI;
use boru\dhutils\traits\JsonTrait;
use boru\dot\Dot;

abstract class BaseModel implements \JsonSerializable {
    use JsonTrait;
    public function __construct($options=[]) {
        $this->setFromData($options);
    }

    private $_extraData = [];

    public function setFromData($options=[]) {
        if($options instanceof ApiBaseResponse) {
            $options = $options->asArray();
        }
        if(!is_array($options) && !is_object($options)) {
            $options = json_decode($options,true);
        }
        if(is_object($options)) {
            $options = (array)$options;
        }
        if(!is_array($options)) {
            throw new \Exception("Invalid options passed to constructor :".
                json_encode($options));
        }
        foreach($options as $key=>$value) {
            if(method_exists($this,$key)) {
                $this->$key($value);
                continue;
            } elseif(strpos($key,"_") !== false) {
                $parts = explode("_",$key);
                $start = array_shift($parts);
                $parts = array_map(function($part) {
                    return ucfirst($part);
                },$parts);
                $key = $start . implode("",$parts);
                if(method_exists($this,$key)) {
                    $this->$key($value);
                    continue;
                } elseif(method_exists($this,strtolower($key))) {
                    $strLowerKey = strtolower($key);
                    $this->$strLowerKey($value);
                    continue;
                }
            }
            $this->_extraData[$key] = $value;
        }
    }

    public function _extra($key=null,$value=null) {
        if($key === null) {
            return $this->_extraData;
        } elseif($value === null) {
            return Dot::get($this->_extraData,$key);
        } else {
            Dot::set($this->_extraData,$key,$value);
        }
    }

    public static function tableName($tableName=null) {
        return "";
    }

    abstract public function toArray();

    public function __toString() {
        return json_encode($this->toArray());
    }
}