<?php
namespace boru\boruai\Models;

use boru\boruai\BoruAI;
use boru\query\Query;
use boru\query\Entity;
use boru\query\models\EntityDefinition;
use boru\boruai\Models\ToolDefinition;
use boru\dhdb\core\Row;
use boru\query\Factory;
use boru\query\models\Value;
use Exception;

class ResponseGroup extends Entity {
    private static $isInit = false;
    public static function entityDefinition() {
        $tableName = BoruAI::table('responseGroups');
        $query = Query::create()->select('id','user','reference','reference','created_at','updated_at','instructions','information','tools','last_response')->from($tableName);
        return new EntityDefinition([
            "className" => static::class,
            "name" => "ResponseGroup",
            "queryBase" => $query,
            "jsonFields" => ['tools'],
            "createdField" => "created_at",
            "updatedField" => "updated_at",
            "idField" => "id",
        ]);
    }

    private $isNewResponseGroup = false;

    public static function doInit() {
        if(!self::$isInit) {
            self::$isInit = true;
            Factory::register(static::entityDefinition());
        }
    }

    public function __construct($input=null) {
        self::doInit();
        parent::__construct($input);
        if(!$this->user()) {
            $this->user(Value::functionValue('0'));
        }
    }

    public function isNewResponseGroup($new=null) {
        if($new !== null) {
            $this->isNewResponseGroup = $new ? true : false;
        }
        return $this->isNewResponseGroup ? true : false;
    }
    public function id() {
        return $this->get("id");
    }

    public function user($user=null) {
        if ($user !== null) {
            $this->set("user",$user);
        }
        return $this->get("user");
    }
    public function reference($reference=null) {
        if ($reference !== null) {
            $this->set("reference",$reference);
        }
        return $this->get("reference");
    }
    public function instructions($instructions=null) {
        if ($instructions !== null) {
            $this->set("instructions",$instructions);
        }
        return $this->get("instructions");
    }
    public function information($information=null) {
        if ($information !== null) {
            $this->set("information",$information);
        }
        return $this->get("information");
    }
    public function tools($tools=null) {
        if ($tools !== null) {
            $this->set("tools",$tools);
        }
        return $this->get("tools");
    }
    public function lastResponse($lastResponse=null) {
        if ($lastResponse !== null) {
            $this->set("last_response",$lastResponse);
        }
        return $this->get("last_response");
    }
    public function createdAt($createdAt=null) {
        if ($createdAt !== null) {
            $this->set("created_at",$createdAt);
        }
        return $this->get("created_at");
    }
    public function updatedAt($updatedAt=null) {
        if ($updatedAt !== null) {
            $this->set("updated_at",$updatedAt);
        }
        return $this->get("updated_at");
    }

    public function getInput() {
        $information = $this->get("information");
        $instructions = $this->get("instructions");
        if(!$information && !$instructions) {
            return false;
        }
        $output = [];
        if($information) {
            $output[] = "Information: ".$information;
        }
        if($instructions) {
            $output[] = "Instructions: ".$instructions;
        }
        if(!empty($output)) {
            $output[] = "Please make sure to retain the important information from this conversation.";
        }
        return "----------\nPreviously known information::\n".implode("\n",$output)."\n----------\n\n";
    }

    /**
     * 
     * @return ToolDefinition[]
     */
    public function initFunctions() {
        \boru\boruai\Models\Functions\ResponseGroup::init($this);
        return \boru\boruai\Models\Functions\ResponseGroup::functionDefinitions();
    }


    /**
     * 
     * @param mixed $reference 
     * @param mixed $user 
     * @param bool $create 
     * @return self|false
     * @throws Exception 
     */
    public static function forReference($reference,$user=null,$create=true) {
        static::doInit();
        $query = Factory::query("ResponseGroup");
        $query->where("reference","=",$reference);
        if($user) {
            $query->where("user","=",$user);
        }
        $query->limit(1);
        $db = BoruAI::db();
        $result = $query->toRow();
        $instance = false;
        if($result) {
            $id = $result->get("id");
            $instance = Factory::instanceById("ResponseGroup",$id);
        }
        if(!$instance && $create) {
            $instance = new static();
            $instance->set("reference",$reference);
            $instance->set("user",$user);
            $instance->isNewResponseGroup(true);
            $instance->save();
        }
        return $instance;
    }
    
}