<?php
namespace boru\boruai\Cli\Defs;

use boru\boruai\BoruAI;
use boru\boruai\Models\ChatSession;
use boru\boruai\Models\Document;
use boru\cli\CLI;
use boru\cli\params\Flag;
use boru\cli\params\Option;
use boru\cli\params\Positional;
use boru\output\Output;
use boru\boruai\Openai\Api\Endpoints\AssistantsAPI;
use boru\boruai\Openai\OpenAIAssistant;
use boru\boruai\Openai\OpenAIChat;

trait SessionCLI {
    public static function def_session() {
        return [
            "description"=> "Chat Session",
            "params" => [
                Positional::create("session|A session name or ID to use. 'new' to create a new session"),
            ]
        ];
    }

    public static function def_session_list() {
        return [
            "description"=> "List Chat Sessions",
            "params" => [
                Option::create("l|limit|The number of sessions to list",["default"=>25]),
                Option::create("o|offset|The offset to start listing from",["default"=>0]),
            ]
        ];
    }

    public function cmd_session_list($cmd) {
        $limit = $cmd->get("limit",25);
        $offset = $cmd->get("offset",0);
        $sessions = ChatSession::listSessions($limit,$offset);
        foreach($sessions as $session) {
            Output::outLine($session->id()."\t".$session->name());
        }
    }

    public static function def_session_delete() {
        return [
            "description"=> "Delete a Chat Session",
            "params" => [
                Positional::create("*session|The session Name or ID to delete"),
            ]
        ];
    }

    public function cmd_session_delete($cmd) {
        $sessionIdOrName = $cmd->get("session");
        $session = ChatSession::fromId($sessionIdOrName);
        if(!$session) {
            $session = ChatSession::fromName($sessionIdOrName);
        }
        if($session) {
            $session->delete();
            Output::outLine("Session",$sessionIdOrName,"deleted..");
        } else {
            Output::outLine("Session",$sessionIdOrName,"not found..");
        }
    }

    public static function def_session_start() {
        return [
            "description"=> "Start a Chat Session",
            "params" => [
                Positional::create("session|A session name or ID to use. 'new' to create a new session"),
            ]
        ];
    }

    public function cmd_session_start($cmd) {
        $sessionIdOrName = $cmd->get("session","new");
        if($sessionIdOrName) {
            if($sessionIdOrName != "new") {
                if(($session = ChatSession::fromName($sessionIdOrName)) === false) {
                    if(($session = ChatSession::fromId($sessionIdOrName)) === false) {
                        $session = new ChatSession(["name"=>$sessionIdOrName]);
                        $session->save();
                        Output::outLine("New Session created");
                        Output::outLine("ID: ".$session->id());
                        Output::outLine("Name: ".$session->name());
                        Output::outLine("------");
                    }
                }
            } else {
                $session = new ChatSession(["name"=>md5(time())]);
                $session->save();
                Output::outLine("New Session created");
                Output::outLine("ID: ".$session->id());
                Output::outLine("Name: ".$session->name());
                Output::outLine("------");
            }
        }
        $messages = $session->getMessages();
        if($messages) {
            foreach($messages as $message) {
                if($message["role"] == "user") {
                    $lines = explode("\n",$message["content"]);
                    foreach($lines as $line) {
                        Output::outLine(" -> ".$line);
                    }
                    Output::outLine("------");
                } else {
                    Output::outLine($message["content"]);
                    Output::outLine("------");
                }
            }
        }
        while(true) {
            $lines = $this->captureSessionInput();
            foreach($lines as $i=>$line) {
                if(substr($line,0,1) == ":") {
                    $cmdParts = explode(" ",substr($line,1));
                    if($cmdParts[0] == "doc" || $cmdParts[0] == "document") {
                        if(count($cmdParts) == 2) {
                            $doc = Document::fromId($cmdParts[1]);
                            if($doc) {
                                $session->addDocument($doc);
                                Output::outLine("Document",$doc->id(),"added..");
                            }
                        }
                        unset($lines[$i]);
                    } elseif($cmdParts[0] == 'inc' || $cmdParts[0] == 'include') {
                        if(count($cmdParts) == 2) {
                            $doc = Document::fromId($cmdParts[1]);
                            if($doc) {
                                //$session->
                                Output::outLine("Document",$doc->id(),"added..");
                            }
                        }
                        unset($lines[$i]);
                    } elseif($cmdParts[0] == 'tool') {
                        if(count($cmdParts) == 2) {
                            $tool = BoruAI::loadTool($cmdParts[1]);
                            if($tool) {
                                $session->addTool($cmdParts[1]);
                                Output::outLine("Tool",$cmdParts[1],"added..");
                            }
                        }
                        unset($lines[$i]);
                    }
                }
            }
            if(empty($lines)) {
                continue;
            }
            $phrase = implode("\n",$lines);
            if($phrase == "/q") {
                break;
            }
            Output::outLine("------");
            Output::outLine($session->chat($phrase));
            Output::outLine("------");
        }
    }


    private function captureSessionInput() {
        $line = "";
        $lines = [];
        Output::outLine("Enter your chat messages. Type '/s' to stop, '/q' to quit.");
        $break = $exit = false;
        while(true) {
            $line = CLI::promptInput(" -> ");
            if(strlen($line)>=2) {
                if(substr($line,-2) == "/q") {
                    $exit = true;
                    $line = substr($line,0,-2);
                }
                if(substr($line,-2) == "/s") {
                    $break = true;
                    $line = substr($line,0,-2);
                }
            }
            $lines[] = $line;
            if($break || $exit) {
                break;
            }
        }
        if($exit) {
            return ["/q"];
        }
        return $lines;
    }
}