<?php
namespace boru\ai\Conversation\Tool;

use boru\ai\AI;
use boru\ai\Conversation\Conversation;
use boru\ai\Conversation\ConversationNote;
use boru\ai\Runtime\AbstractTool;
use boru\ai\Runtime\ToolExecutionContext;
use boru\ai\Runtime\ToolPromptAdditionInterface;

class AppendConversationNoteTool extends AbstractTool implements ToolPromptAdditionInterface
{
    public function name()
    {
        return 'append_conversation_note';
    }

    public function description()
    {
        return 'Append a structured note to the current conversation memory.';
    }

    public function schema()
    {
        return array(
            'type' => 'object',
            'properties' => array(
                'text' => array(
                    'type' => 'string',
                    'description' => 'The note text to add.',
                ),
                'kind' => array(
                    'type' => 'string',
                    'description' => 'Note kind such as fact, preference, decision, task, or constraint.',
                ),
                'confidence' => array(
                    'type' => 'number',
                    'description' => 'Optional confidence from 0 to 1.',
                ),
            ),
            'required' => array('text'),
        );
    }

    public function promptAddition()
    {
        return 'When you learn durable facts, preferences, decisions, tasks, or constraints that should persist across turns, append a structured conversation note.';
    }

    public function handle(array $arguments, ToolExecutionContext $context = null)
    {
        $conversation = $this->requireConversation($context);

        $note = new ConversationNote();
        $note->text(isset($arguments['text']) ? $arguments['text'] : '');
        $note->kind(isset($arguments['kind']) && $arguments['kind'] !== '' ? $arguments['kind'] : 'note');
        if (isset($arguments['confidence'])) {
            $note->confidence($arguments['confidence']);
        }

        $turnNumber = $this->inferSourceTurnNumber($conversation);
        if ($turnNumber !== null) {
            $note->sourceTurnNumber($turnNumber);
        }

        $conversation->memory()->addNote($note);
        AI::persistence()->saveConversation($conversation);
        return $note->toArray();
    }

    protected function requireConversation(ToolExecutionContext $context = null)
    {
        $request = $context ? $context->request() : null;
        $conversation = $request ? $request->metadata('conversation') : null;
        if (!$conversation instanceof Conversation) {
            throw new \RuntimeException('Conversation memory tools require an active conversation context');
        }
        return $conversation;
    }

    protected function inferSourceTurnNumber(Conversation $conversation)
    {
        $turn = $conversation->latestTurn();
        if (!$turn) {
            return null;
        }
        return $turn->number();
    }
}
