<?php
namespace boru\boruai\Vtiger;

use boru\boruai\BoruAI;
use boru\boruai\Models\ToolDefinition;
use boru\boruai\Openai\OpenAIChat;
use boru\boruai\models\ChatSession;
use boru\boruai\Vtiger\VtigerToolFunctions;

class VtigerQuery {
    private $chat;
    private $model = "gpt-4o";
    private $session;
    private $info = [
        "When getting information from vtiger modules, the spelling and capitalization must be exact. For example, 'Account' cannot be queried, but 'Accounts' can be queried. Only utilize the exact spelling needed.",
    ];
    private $toolDefinitions = [];
    public function __construct($model="gpt-4o",$extraToolDefinitions=[]) {
        $this->setToolDefinitions($extraToolDefinitions);
    }

    public function info($dataInformation) {
        if(is_array($dataInformation)) {
            foreach($dataInformation as $info) {
                $this->info($info);
            }
        } elseif(is_string($dataInformation)) {
            $this->info[] = $dataInformation;
            if($this->session !== null) {
                $this->session->addMessage("system", $dataInformation);
            } elseif($this->chat !== null) {
                $this->chat->addMessage("system", $dataInformation);
            }
        }
    }

    public function session($session=null) {
        if($session !== null) {
            $sessionObj = null;
            if(is_string($session) || is_numeric($session)) {
                $sessionObj = ChatSession::fromId($session);
                if(!$sessionObj instanceof ChatSession) {
                    $sessionObj = ChatSession::fromName($session);
                }
            }

            if(!$sessionObj instanceof ChatSession) {
                if(is_array($session)) {
                    $sessionObj = new ChatSession($session);
                } elseif(is_string($session) || is_numeric($session)) {
                    $sessionObj = new ChatSession(["name"=>$session]);
                    $sessionObj->save();
                    BoruAI::printDebug("Session created: ".$sessionObj->id());
                    BoruAI::printDebug("New Session ". $sessionObj->id() ." created:" . $sessionObj->name());
                } else {
                    throw new \Exception("Session must be a string, numeric, or ChatSession object");
                }
            }
            $this->session = $sessionObj;
            return $this;
        }
        return $this->session;
    }
    
    public function setToolDefinitions($toolDefinitions=[]) {
        if($toolDefinitions === null || empty($toolDefinitions)) {
            $toolDefinitions = [];
        }
        $this->toolDefinitions = ToolDefinition::merge($toolDefinitions, VtigerToolFunctions::createFunctionDefinitions());
    }
    public function model($model=null) {
        if($model !== null) {
            $this->model = $model;
            if($this->session !== null) {
                $this->session->set("model",$model);
            }
        }
        return $this->model;
    }

    public function query($query) {
        if($this->session !== null) {
            return $this->querySession($query);
        }
        return $this->queryChat($query);
    }

    public function queryChat($query,$contentOnly=true) {
        if($this->chat === null) {
            $this->chat = new OpenAIChat();
            foreach($this->toolDefinitions as $toolDefinition) {
                $this->chat->addTool($toolDefinition);
            }
            foreach($this->info as $info) {
                $this->chat->addMessage("system", $info);
            }
        }
        if(is_array($query)) {
            $query = implode(" ",$query);
        }
        $this->chat->addMessage("user", $query);
        return $this->chat->run(0,$contentOnly);
    }

    public function querySession($query) {
        if($this->session === null) {
            $this->session = new ChatSession();
        }
        if(empty($this->session->important())) {
            $this->session->addTool("Vtiger");
            foreach($this->info as $info) {
                $this->session->addMessage("system", $info);
            }
            $this->session->save();
        }
        if(is_array($query)) {
            $query = implode(" ",$query);
        }
        $this->session->addMessage("user", $query);
        return $this->session->chat($query);
    }
}